Last active
November 4, 2015 23:05
-
-
Save mdwhatcott/bc84abca4aaa5238e751 to your computer and use it in GitHub Desktop.
One way to validate struct fields that are strings, and that have a struct tag with a regex.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package web | |
import ( | |
"bytes" | |
"reflect" | |
"regexp" | |
"fmt" | |
"errors" | |
"strings" | |
) | |
func Validate(s interface{}) error { | |
problems := &bytes.Buffer{} | |
value := reflect.ValueOf(s) | |
type_ := reflect.TypeOf(s) | |
for i := 0; i < type_.NumField(); i++ { | |
field := type_.Field(i) | |
if field.Type.Kind() != reflect.String { | |
continue | |
} | |
fullTag := string(field.Tag) | |
required := fullTag == "required" || strings.Contains(fullTag, " required") || strings.Contains(fullTag, "required ") | |
input := value.Field(i).String() | |
if required && len(input) == 0 { | |
fmt.Fprintf(problems, "Missing required field ('%s').\n", field.Name) | |
continue | |
} | |
tag := field.Tag.Get("validate") | |
if len(tag) == 0 { | |
continue | |
} | |
re, err := regexp.Compile(tag) | |
if err != nil { | |
return err | |
} | |
if !re.MatchString(input) { | |
fmt.Fprintf(problems, "Invalid field ('%s'): '%s'\n", field.Name, input) | |
} | |
} | |
if problems.Len() > 0 { | |
return errors.New(problems.String()) | |
} | |
return nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package web | |
import ( | |
"testing" | |
"github.com/smartystreets/assertions" | |
"github.com/smartystreets/assertions/should" | |
) | |
type Input struct { | |
Field1 string `validate:"^Hello World$" required` | |
Field2 int | |
} | |
func TestValidationUsingStructTags(t *testing.T) { | |
assert := assertions.New(t) | |
good := Input{Field1:"Hello World"} | |
bad := Input{Field1:"Hello, Universe"} | |
missing := Input{Field1:""} | |
assert.So(Validate(good), should.BeNil) | |
assert.So(Validate(bad).Error(), should.ContainSubstring, "Invalid field ('Field1'): 'Hello, Universe'") | |
assert.So(Validate(missing).Error(), should.ContainSubstring, "Missing required field ('Field1').") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment