add required_with_all validator

pull/469/head
A Mashmooli 6 years ago
parent 1e6bddb6b3
commit ebfddc5784
  1. 47
      baked_in.go
  2. 21
      validator_test.go

@ -64,6 +64,7 @@ var (
bakedInValidators = map[string]Func{ bakedInValidators = map[string]Func{
"required": hasValue, "required": hasValue,
"required_with": requiredWith, "required_with": requiredWith,
"required_with_all": requiredWithAll,
"isdefault": isDefault, "isdefault": isDefault,
"len": hasLengthOf, "len": hasLengthOf,
"min": hasMinOf, "min": hasMinOf,
@ -1315,7 +1316,7 @@ func hasValue(fl FieldLevel) bool {
} }
// RequiredWith is the validation function // RequiredWith is the validation function
// the field under validation must be present and not empty only if any of the other specified fields are present. // The field under validation must be present and not empty only if any of the other specified fields are present.
func requiredWith(fl FieldLevel) bool { func requiredWith(fl FieldLevel) bool {
field := fl.Field() field := fl.Field()
@ -1329,6 +1330,9 @@ func requiredWith(fl FieldLevel) bool {
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func: case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
isParamFieldPresent = !paramField.IsNil() isParamFieldPresent = !paramField.IsNil()
default: default:
if fl.(*validate).fldIsPointer && paramField.Interface() != nil {
isParamFieldPresent = true
}
isParamFieldPresent = paramField.IsValid() && paramField.Interface() != reflect.Zero(field.Type()).Interface() isParamFieldPresent = paramField.IsValid() && paramField.Interface() != reflect.Zero(field.Type()).Interface()
} }
@ -1348,6 +1352,47 @@ func requiredWith(fl FieldLevel) bool {
return true return true
} }
// RequiredWithAll is the validation function
// The field under validation must be present and not empty only if all of the other specified fields are present.
func requiredWithAll(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 {

@ -8639,3 +8639,24 @@ func TestRequiredWith(t *testing.T) {
t.Fatalf("failed Error: %s", errs) t.Fatalf("failed Error: %s", errs)
} }
} }
func TestRequiredWithAll(t *testing.T) {
test := struct {
Field1 string `validate:"omitempty" json:"field_1"`
Field2 string `validate:"omitempty" json:"field_2"`
Field3 string `validate:"required_with_all=Field1 Field2" json:"field_3"`
}{
Field1: "test_field1",
Field2: "test_field2",
Field3: "test_field3",
}
validate := New()
errs := validate.Struct(test)
if errs != nil {
t.Fatalf("failed Error: %s", errs)
}
}

Loading…
Cancel
Save