feat(unique): Add support for struct memember validation (#1048)

This allows validating that two struct memebers are unique. This has
been documented as a feature, but has never been actually implemented.
pull/1081/head
zemzale 1 year ago committed by GitHub
parent cc768b176d
commit 1c1f70d35b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      baked_in.go
  2. 35
      validator_test.go

@ -335,6 +335,19 @@ func isUnique(fl FieldLevel) bool {
return field.Len() == m.Len()
default:
if parent := fl.Parent(); parent.Kind() == reflect.Struct {
uniqueField := parent.FieldByName(param)
if uniqueField == reflect.ValueOf(nil) {
panic(fmt.Sprintf("Bad field name provided %s", param))
}
if uniqueField.Kind() != field.Kind() {
panic(fmt.Sprintf("Bad field type %T:%T", field.Interface(), uniqueField.Interface()))
}
return field.Interface() != uniqueField.Interface()
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
}

@ -9991,6 +9991,41 @@ func TestUniqueValidation(t *testing.T) {
}
}
PanicMatches(t, func() { _ = validate.Var(1.0, "unique") }, "Bad field type float64")
t.Run("struct", func(t *testing.T) {
tests := []struct {
param interface{}
expected bool
}{
{struct {
A string `validate:"unique=B"`
B string
}{A: "abc", B: "bcd"}, true},
{struct {
A string `validate:"unique=B"`
B string
}{A: "abc", B: "abc"}, false},
}
validate := New()
for i, test := range tests {
errs := validate.Struct(test.param)
if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d unique failed Error: %v", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d unique failed Error: %v", i, errs)
} else {
val := getError(errs, "A", "A")
if val.Tag() != "unique" {
t.Fatalf("Index: %d unique failed Error: %v", i, errs)
}
}
}
}
})
}
func TestUniqueValidationStructSlice(t *testing.T) {

Loading…
Cancel
Save