forked from Fuyu/validate
Support pointer values
This commit is contained in:
parent
cb4720cd31
commit
43deea02af
@ -131,6 +131,7 @@ func TestLenMinMax(t *testing.T) {
|
||||
}
|
||||
|
||||
func check(t *testing.T, c interface{}, errCount int) {
|
||||
t.Helper()
|
||||
errs := Validate(c)
|
||||
if len(errs) != errCount {
|
||||
t.Errorf(`Case %T(%v) should get %d errors, but got %v`, c, c, errCount, errs)
|
||||
|
31
validate.go
31
validate.go
@ -159,10 +159,17 @@ func getRules(rt reflect.Type) []rule {
|
||||
|
||||
for i := 0; i < rt.NumField(); i++ {
|
||||
ft := rt.Field(i)
|
||||
kind := simplifyKind(ft.Type.Kind())
|
||||
|
||||
kind := ft.Type.Kind()
|
||||
var ptr bool
|
||||
if kind == reflect.Ptr {
|
||||
kind = ft.Type.Elem().Kind()
|
||||
ptr = true
|
||||
}
|
||||
kind = simplifyKind(kind)
|
||||
|
||||
tags := strings.Split(ft.Tag.Get(`validate`), `,`)
|
||||
rules = append(rules, getTagFuncs(i, ft, kind, tags)...)
|
||||
rules = append(rules, getTagFuncs(i, ft, kind, tags, ptr)...)
|
||||
|
||||
// TODO: Add validator interface
|
||||
|
||||
@ -185,7 +192,7 @@ func nest(ft reflect.StructField) func(reflect.Value) ([]ValidationError, bool)
|
||||
}
|
||||
}
|
||||
|
||||
func getTagFuncs(i int, ft reflect.StructField, kind reflect.Kind, tags []string) []rule {
|
||||
func getTagFuncs(i int, ft reflect.StructField, kind reflect.Kind, tags []string, ptr bool) []rule {
|
||||
var rules []rule
|
||||
for _, v := range tags {
|
||||
if v == `` {
|
||||
@ -198,6 +205,13 @@ func getTagFuncs(i int, ft reflect.StructField, kind reflect.Kind, tags []string
|
||||
value = parts[1]
|
||||
}
|
||||
|
||||
kind := kind
|
||||
ptr := ptr
|
||||
if ptr && (tag == `optional` || strings.TrimPrefix(tag, `!`) == `required`) {
|
||||
kind = reflect.Ptr
|
||||
ptr = false
|
||||
}
|
||||
|
||||
if tag == `optional` {
|
||||
rules = append(rules, rule{i, func(rv reflect.Value) ([]ValidationError, bool) {
|
||||
check, _ := getTagFunc(`required`, ``, kind)
|
||||
@ -221,6 +235,17 @@ func getTagFuncs(i int, ft reflect.StructField, kind reflect.Kind, tags []string
|
||||
return []ValidationError{{Field: []Field{{nil, &ft}}, Check: tag, Value: value}}, false
|
||||
}
|
||||
|
||||
if ptr {
|
||||
oldF := f
|
||||
f = func(rv reflect.Value) ([]ValidationError, bool) {
|
||||
if rv.IsNil() {
|
||||
return []ValidationError{{Field: []Field{{nil, &ft}}, Check: tag, Value: value}}, false
|
||||
}
|
||||
|
||||
return oldF(rv.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
rules = append(rules, rule{i, f})
|
||||
}
|
||||
|
||||
|
@ -97,3 +97,24 @@ func TestNot(t *testing.T) {
|
||||
t.Errorf(`Checknames missing !, got "%s" and "%s"`, errs[0].Check, errs[1].Check)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPtr(t *testing.T) {
|
||||
type s struct {
|
||||
A *int `validate:"eq=3"`
|
||||
B *int `validate:"optional,eq=3"`
|
||||
}
|
||||
|
||||
two := 2
|
||||
three := 3
|
||||
|
||||
var pass1 = s{&three, &three}
|
||||
var pass2 = s{&three, nil}
|
||||
|
||||
var fail1 = s{&two, &two}
|
||||
var fail2 = s{nil, nil}
|
||||
|
||||
check(t, pass1, 0)
|
||||
check(t, pass2, 0)
|
||||
check(t, fail1, 2)
|
||||
check(t, fail2, 1)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user