From b7cdec1ddb9e33a55cea03a32935b42ad241b20a Mon Sep 17 00:00:00 2001 From: Marine Bal Date: Mon, 23 May 2022 10:22:20 +0000 Subject: [PATCH] Feat: support slice on isOneOf --- baked_in.go | 25 +++++++++++++++++++----- validator_test.go | 49 ++++++++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/baked_in.go b/baked_in.go index f2f0939..0fdc746 100644 --- a/baked_in.go +++ b/baked_in.go @@ -250,11 +250,7 @@ func isHTML(fl FieldLevel) bool { return hTMLRegex.MatchString(fl.Field().String()) } -func isOneOf(fl FieldLevel) bool { - vals := parseOneOfParam2(fl.Param()) - - field := fl.Field() - +func checkIsOneOf(field reflect.Value, vals []string) bool { var v string switch field.Kind() { case reflect.String: @@ -266,6 +262,7 @@ func isOneOf(fl FieldLevel) bool { default: panic(fmt.Sprintf("Bad field type %T", field.Interface())) } + for i := 0; i < len(vals); i++ { if vals[i] == v { return true @@ -274,6 +271,24 @@ func isOneOf(fl FieldLevel) bool { return false } +func isOneOf(fl FieldLevel) bool { + vals := parseOneOfParam2(fl.Param()) + field := fl.Field() + + value, kind, _ := fl.ExtractType(field) + if kind == reflect.Slice { + for i := 0; i < value.Len(); i++ { + if !checkIsOneOf(value.Index(i), vals) { + return false + } + } + + return true + } + + return checkIsOneOf(field, vals) +} + // isUnique is the validation function for validating if each array|slice|map value is unique func isUnique(fl FieldLevel) bool { field := fl.Field() diff --git a/validator_test.go b/validator_test.go index 1ebdea5..ac7ac6d 100644 --- a/validator_test.go +++ b/validator_test.go @@ -5493,10 +5493,13 @@ func TestOneOfValidation(t *testing.T) { }{ {f: "red", t: "oneof=red green"}, {f: "green", t: "oneof=red green"}, + {f: []string{"red", "green"}, t: "oneof=red green"}, {f: "red green", t: "oneof='red green' blue"}, {f: "blue", t: "oneof='red green' blue"}, + {f: []string{"red green", "blue"}, t: "oneof='red green' blue"}, {f: 5, t: "oneof=5 6"}, {f: 6, t: "oneof=5 6"}, + {f: []int{6, 5}, t: "oneof=5 6"}, {f: int8(6), t: "oneof=5 6"}, {f: int16(6), t: "oneof=5 6"}, {f: int32(6), t: "oneof=5 6"}, @@ -5521,9 +5524,11 @@ func TestOneOfValidation(t *testing.T) { {f: "", t: "oneof=red green"}, {f: "yellow", t: "oneof=red green"}, {f: "green", t: "oneof='red green' blue"}, + {f: []string{"green", "blue"}, t: "oneof='red green' blue"}, {f: 5, t: "oneof=red green"}, {f: 6, t: "oneof=red green"}, {f: 6, t: "oneof=7"}, + {f: []int{6, 7}, t: "oneof=7"}, {f: uint(6), t: "oneof=7"}, {f: int8(5), t: "oneof=red green"}, {f: int16(5), t: "oneof=red green"}, @@ -12264,25 +12269,25 @@ func TestCreditCardFormatValidation(t *testing.T) { } func TestMultiOrOperatorGroup(t *testing.T) { - tests := []struct { - Value int `validate:"eq=1|gte=5,eq=1|lt=7"` - expected bool - }{ - {1, true}, {2, false}, {5, true}, {6, true}, {8, false}, - } - - validate := New() - - for i, test := range tests { - errs := validate.Struct(test) - if test.expected { - if !IsEqual(errs, nil) { - t.Fatalf("Index: %d multi_group_of_OR_operators failed Error: %s", i, errs) - } - } else { - if IsEqual(errs, nil) { - t.Fatalf("Index: %d multi_group_of_OR_operators should have errs", i) - } - } - } - } + tests := []struct { + Value int `validate:"eq=1|gte=5,eq=1|lt=7"` + expected bool + }{ + {1, true}, {2, false}, {5, true}, {6, true}, {8, false}, + } + + validate := New() + + for i, test := range tests { + errs := validate.Struct(test) + if test.expected { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d multi_group_of_OR_operators failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d multi_group_of_OR_operators should have errs", i) + } + } + } +}