Skip to content

Commit 9c415c4

Browse files
Add support for excluded_with on pointer fields (#746)
1 parent f6584a4 commit 9c415c4

File tree

2 files changed

+95
-2
lines changed

2 files changed

+95
-2
lines changed

validator_instance.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ const (
2929
requiredWithAllTag = "required_with_all"
3030
requiredIfTag = "required_if"
3131
requiredUnlessTag = "required_unless"
32+
excludedWithoutAllTag = "excluded_without_all"
33+
excludedWithoutTag = "excluded_without"
34+
excludedWithTag = "excluded_with"
35+
excludedWithAllTag = "excluded_with_all"
3236
skipValidationTag = "-"
3337
diveTag = "dive"
3438
keysTag = "keys"
@@ -111,7 +115,8 @@ func New() *Validate {
111115

112116
switch k {
113117
// these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour
114-
case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag:
118+
case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag,
119+
excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag:
115120
_ = v.registerValidation(k, wrapFunc(val), true, true)
116121
default:
117122
// no need to error check here, baked in will always be valid

validator_test.go

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10202,6 +10202,28 @@ func TestExcludedWith(t *testing.T) {
1020210202
name := fmt.Sprintf("Field%d", i)
1020310203
AssertError(t, errs, name, name, name, name, "excluded_with")
1020410204
}
10205+
10206+
test3 := struct {
10207+
Inner *Inner
10208+
Inner2 *Inner
10209+
Field string `validate:"omitempty" json:"field"`
10210+
FieldE string `validate:"omitempty" json:"field_e"`
10211+
Field1 string `validate:"excluded_with=FieldE" json:"field_1"`
10212+
Field2 *string `validate:"excluded_with=FieldE" json:"field_2"`
10213+
Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
10214+
Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"`
10215+
Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"`
10216+
Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
10217+
}{
10218+
Inner: &Inner{FieldE: "populated"},
10219+
Inner2: &Inner{FieldE: "populated"},
10220+
FieldE: "populated",
10221+
}
10222+
10223+
validate = New()
10224+
10225+
errs = validate.Struct(test3)
10226+
Equal(t, errs, nil)
1020510227
}
1020610228

1020710229
func TestExcludedWithout(t *testing.T) {
@@ -10266,6 +10288,26 @@ func TestExcludedWithout(t *testing.T) {
1026610288
name := fmt.Sprintf("Field%d", i)
1026710289
AssertError(t, errs, name, name, name, name, "excluded_without")
1026810290
}
10291+
10292+
test3 := struct {
10293+
Inner *Inner
10294+
Inner2 *Inner
10295+
Field string `validate:"omitempty" json:"field"`
10296+
FieldE string `validate:"omitempty" json:"field_e"`
10297+
Field1 string `validate:"excluded_without=Field" json:"field_1"`
10298+
Field2 *string `validate:"excluded_without=Field" json:"field_2"`
10299+
Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
10300+
Field4 interface{} `validate:"excluded_without=Field" json:"field_4"`
10301+
Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"`
10302+
}{
10303+
Inner: &Inner{Field: &fieldVal},
10304+
Field: "populated",
10305+
}
10306+
10307+
validate = New()
10308+
10309+
errs = validate.Struct(test3)
10310+
Equal(t, errs, nil)
1026910311
}
1027010312

1027110313
func TestExcludedWithAll(t *testing.T) {
@@ -10334,6 +10376,29 @@ func TestExcludedWithAll(t *testing.T) {
1033410376
name := fmt.Sprintf("Field%d", i)
1033510377
AssertError(t, errs, name, name, name, name, "excluded_with_all")
1033610378
}
10379+
10380+
test3 := struct {
10381+
Inner *Inner
10382+
Inner2 *Inner
10383+
Field string `validate:"omitempty" json:"field"`
10384+
FieldE string `validate:"omitempty" json:"field_e"`
10385+
Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"`
10386+
Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"`
10387+
Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
10388+
Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"`
10389+
Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
10390+
Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
10391+
}{
10392+
Inner: &Inner{FieldE: "populated"},
10393+
Inner2: &Inner{FieldE: "populated"},
10394+
Field: "populated",
10395+
FieldE: "populated",
10396+
}
10397+
10398+
validate = New()
10399+
10400+
errs = validate.Struct(test3)
10401+
Equal(t, errs, nil)
1033710402
}
1033810403

1033910404
func TestExcludedWithoutAll(t *testing.T) {
@@ -10352,9 +10417,10 @@ func TestExcludedWithoutAll(t *testing.T) {
1035210417
Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
1035310418
Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
1035410419
Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"`
10355-
Field5 string `validate:"excluded_without_all=Inner.Field Inner.Field2" json:"field_5"`
10420+
Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
1035610421
}{
1035710422
Inner: &Inner{Field: &fieldVal},
10423+
Inner2: &Inner{Field: &fieldVal},
1035810424
Field: "populated",
1035910425
Field1: fieldVal,
1036010426
Field2: &fieldVal,
@@ -10398,6 +10464,28 @@ func TestExcludedWithoutAll(t *testing.T) {
1039810464
name := fmt.Sprintf("Field%d", i)
1039910465
AssertError(t, errs, name, name, name, name, "excluded_without_all")
1040010466
}
10467+
10468+
test3 := struct {
10469+
Inner *Inner
10470+
Inner2 *Inner
10471+
Field string `validate:"omitempty" json:"field"`
10472+
FieldE string `validate:"omitempty" json:"field_e"`
10473+
Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"`
10474+
Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
10475+
Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
10476+
Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"`
10477+
Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
10478+
}{
10479+
Inner: &Inner{Field: &fieldVal},
10480+
Inner2: &Inner{Field: &fieldVal},
10481+
Field: "populated",
10482+
FieldE: "populated",
10483+
}
10484+
10485+
validate = New()
10486+
10487+
errs = validate.Struct(test3)
10488+
Equal(t, errs, nil)
1040110489
}
1040210490

1040310491
func TestRequiredWithAll(t *testing.T) {

0 commit comments

Comments
 (0)