Add nostructlevel tag

* nostructlevel - Same as structonly tag except that any struct level
		  validations will not run.
pull/209/head
joeybloggs 9 years ago
parent 27557e4813
commit 24c1c6819f
  1. 3
      doc.go
  2. 1
      util.go
  3. 6
      validator.go
  4. 31
      validator_test.go

@ -138,6 +138,9 @@ Here is a list of the current built in validators:
you know the struct will be valid, but need to verify it has been assigned. you know the struct will be valid, but need to verify it has been assigned.
NOTE: only "required" and "omitempty" can be used on a struct itself. NOTE: only "required" and "omitempty" can be used on a struct itself.
nostructlevel
Same as structonly tag except that any struct level validations will not run.
exists exists
Is a special tag without a validation function attached. It is used when a field Is a special tag without a validation function attached. It is used when a field
is a Pointer, Interface or Invalid and you wish to validate that it exists. is a Pointer, Interface or Invalid and you wish to validate that it exists.

@ -26,6 +26,7 @@ var (
skipValidationTag: emptyStructPtr, skipValidationTag: emptyStructPtr,
utf8HexComma: emptyStructPtr, utf8HexComma: emptyStructPtr,
utf8Pipe: emptyStructPtr, utf8Pipe: emptyStructPtr,
noStructLevelTag: emptyStructPtr,
} }
) )

@ -26,6 +26,7 @@ const (
orSeparator = "|" orSeparator = "|"
tagKeySeparator = "=" tagKeySeparator = "="
structOnlyTag = "structonly" structOnlyTag = "structonly"
noStructLevelTag = "nostructlevel"
omitempty = "omitempty" omitempty = "omitempty"
skipValidationTag = "-" skipValidationTag = "-"
diveTag = "dive" diveTag = "dive"
@ -595,6 +596,11 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
typ = current.Type() typ = current.Type()
if typ != timeType { if typ != timeType {
if strings.Contains(tag, noStructLevelTag) {
return
}
v.tranverseStruct(topStruct, current, current, errPrefix+name+".", errs, false, partial, exclude, includeExclude, strings.Contains(tag, structOnlyTag)) v.tranverseStruct(topStruct, current, current, errPrefix+name+".", errs, false, partial, exclude, includeExclude, strings.Contains(tag, structOnlyTag))
return return
} }

@ -3493,6 +3493,36 @@ func TestBase64Validation(t *testing.T) {
AssertError(t, errs, "", "", "base64") AssertError(t, errs, "", "", "base64")
} }
func TestNoStructLevelValidation(t *testing.T) {
type Inner struct {
Test string `validate:"len=5"`
}
type Outer struct {
InnerStruct *Inner `validate:"required,nostructlevel"`
}
outer := &Outer{
InnerStruct: nil,
}
errs := validate.Struct(outer)
NotEqual(t, errs, nil)
AssertError(t, errs, "Outer.InnerStruct", "InnerStruct", "required")
inner := &Inner{
Test: "1234",
}
outer = &Outer{
InnerStruct: inner,
}
errs = validate.Struct(outer)
Equal(t, errs, nil)
}
func TestStructOnlyValidation(t *testing.T) { func TestStructOnlyValidation(t *testing.T) {
type Inner struct { type Inner struct {
@ -3509,6 +3539,7 @@ func TestStructOnlyValidation(t *testing.T) {
errs := validate.Struct(outer) errs := validate.Struct(outer)
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "Outer.InnerStruct", "InnerStruct", "required")
inner := &Inner{ inner := &Inner{
Test: "1234", Test: "1234",

Loading…
Cancel
Save