add required_without_all validator

pull/469/head
A Mashmooli 6 years ago
parent 03bfd38cc1
commit 3ec10f9949
  1. 42
      baked_in.go
  2. 19
      validator_test.go

@ -66,6 +66,7 @@ var (
"required_with": requiredWith, "required_with": requiredWith,
"required_with_all": requiredWithAll, "required_with_all": requiredWithAll,
"required_without": requiredWithout, "required_without": requiredWithout,
"required_without_all": requiredWithoutAll,
"isdefault": isDefault, "isdefault": isDefault,
"len": hasLengthOf, "len": hasLengthOf,
"min": hasMinOf, "min": hasMinOf,
@ -1435,6 +1436,47 @@ func requiredWithout(fl FieldLevel) bool {
return true return true
} }
// RequiredWithoutAll is the validation function
// The field under validation must be present and not empty only when all of the other specified fields are not present.
func requiredWithoutAll(fl FieldLevel) bool {
field := fl.Field()
isValidateCurrentField := true
params := parseOneOfParam2(fl.Param())
for _, param := range params {
isParamFieldPresent := false
paramField := fl.Parent().FieldByName(param)
switch paramField.Kind() {
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
isParamFieldPresent = !paramField.IsNil()
default:
if fl.(*validate).fldIsPointer && paramField.Interface() != nil {
isParamFieldPresent = true
}
isParamFieldPresent = paramField.IsValid() && paramField.Interface() != reflect.Zero(field.Type()).Interface()
}
if isParamFieldPresent {
isValidateCurrentField = !isParamFieldPresent
}
}
if isValidateCurrentField {
switch field.Kind() {
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
return !field.IsNil()
default:
if fl.(*validate).fldIsPointer && field.Interface() != nil {
return true
}
return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
}
}
return true
}
// IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value. // IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value.
func isGteField(fl FieldLevel) bool { func isGteField(fl FieldLevel) bool {

@ -8678,3 +8678,22 @@ func TestRequiredWithout(t *testing.T) {
t.Fatalf("failed Error: %s", errs) t.Fatalf("failed Error: %s", errs)
} }
} }
func TestRequiredWithoutAll(t *testing.T) {
test := struct {
Field1 string `validate:"omitempty" json:"field_1"`
Field2 string `validate:"omitempty" json:"field_2"`
Field3 string `validate:"required_without_all=Field1 Field2" json:"field_3"`
}{
Field3: "test_field3",
}
validate := New()
errs := validate.Struct(test)
if errs != nil {
t.Fatalf("failed Error: %s", errs)
}
}

Loading…
Cancel
Save