mirror of
https://github.com/Fishwaldo/validator.git
synced 2025-07-08 05:59:42 +00:00
add required_without_all validator
This commit is contained in:
parent
03bfd38cc1
commit
3ec10f9949
2 changed files with 163 additions and 102 deletions
42
baked_in.go
42
baked_in.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…
Add table
Add a link
Reference in a new issue