diff --git a/tagexpr.go b/tagexpr.go index c68d60c..8316ea0 100644 --- a/tagexpr.go +++ b/tagexpr.go @@ -310,19 +310,27 @@ func (s *structVM) copySubFields(field *fieldVM, sub *structVM) { nameSpace := field.structField.Name offset := field.offset ptrDeep := field.ptrDeep - omitExpr := field.tagOp == tagOmit + tagOp := field.tagOp + omitExpr := tagOp == tagOmit for _, k := range sub.fieldSelectorList { v := sub.fields[k] valueGetter := v.valueGetter reflectValueGetter := v.reflectValueGetter f := &fieldVM{ - structField: v.structField, - offset: offset + v.offset, - origin: v.origin, - exprs: make(map[string]*Expr, len(v.exprs)), + structField: v.structField, + offset: offset, + exprs: make(map[string]*Expr, len(v.exprs)), + ptrDeep: v.ptrDeep, + elemType: v.elemType, + elemKind: v.elemKind, + origin: v.origin, + mapKeyStructVM: v.mapKeyStructVM, + mapOrSliceElemStructVM: v.mapOrSliceElemStructVM, + mapOrSliceIfaceKinds: v.mapOrSliceIfaceKinds, } if !omitExpr { + f.tagOp = v.tagOp var selector string for k, v := range v.exprs { selector = nameSpace + FieldSeparator + k @@ -330,6 +338,8 @@ func (s *structVM) copySubFields(field *fieldVM, sub *structVM) { s.exprs[selector] = v s.exprSelectorList = append(s.exprSelectorList, selector) } + } else { + f.tagOp = tagOp } if valueGetter != nil { diff --git a/tagexpr_test.go b/tagexpr_test.go index 4416f0e..f9b438c 100644 --- a/tagexpr_test.go +++ b/tagexpr_test.go @@ -717,12 +717,13 @@ func TestNilField(t *testing.T) { type ( N struct { X string `tagexpr:"len($)>0"` - N *N `tagexpr:"?"` S []*N `tagexpr:"?"` M map[string]*N `tagexpr:"?"` I interface{} `tagexpr:"-"` MI map[string]interface{} `tagexpr:"?"` SI []interface{} + *N `tagexpr:"?"` + N2 *N `tagexpr:"?"` } M struct { X string `tagexpr:"len($)>0"` @@ -730,7 +731,6 @@ func TestNilField(t *testing.T) { ) n := &N{ X: "n", - N: nil, S: []*N{nil}, M: map[string]*N{"": nil}, I: new(N), diff --git a/validator/README.md b/validator/README.md index 2c3c5cf..04f7092 100644 --- a/validator/README.md +++ b/validator/README.md @@ -27,11 +27,14 @@ import ( func Example() { type InfoRequest struct { - Name string `vd:"($!='Alice'||(Age)$==18) && regexp('\\w')"` - Age int `vd:"$>0"` - Email string `vd:"email($)"` - Phone1 string `vd:"phone($)"` - Phone2 string `vd:"phone($,'CN')"` + Name string `vd:"($!='Alice'||(Age)$==18) && regexp('\\w')"` + Age int `vd:"$>0"` + Email string `vd:"email($)"` + Phone1 string `vd:"phone($)"` + Phone2 string `vd:"phone($,'CN')"` + *InfoRequest `vd:"?"` + Info1 *InfoRequest `vd:"?"` + Info2 *InfoRequest `vd:"-"` } info := InfoRequest{ Name: "Alice", diff --git a/validator/example_test.go b/validator/example_test.go index b5fa677..623a82d 100644 --- a/validator/example_test.go +++ b/validator/example_test.go @@ -8,11 +8,14 @@ import ( func Example() { type InfoRequest struct { - Name string `vd:"($!='Alice'||(Age)$==18) && regexp('\\w')"` - Age int `vd:"$>0"` - Email string `vd:"email($)"` - Phone1 string `vd:"phone($)"` - Phone2 string `vd:"phone($,'CN')"` + Name string `vd:"($!='Alice'||(Age)$==18) && regexp('\\w')"` + Age int `vd:"$>0"` + Email string `vd:"email($)"` + Phone1 string `vd:"phone($)"` + Phone2 string `vd:"phone($,'CN')"` + *InfoRequest `vd:"?"` + Info1 *InfoRequest `vd:"?"` + Info2 *InfoRequest `vd:"-"` } info := InfoRequest{ Name: "Alice",