From c2efe16dc0cf3d04cf982141b41d09587ebf64cb Mon Sep 17 00:00:00 2001 From: Aneurin Barker Snook Date: Sat, 7 Oct 2023 11:24:34 +0100 Subject: [PATCH] add generic in/not in validation --- in.go | 27 +++++++++++++++++++++ in_test.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 in.go create mode 100644 in_test.go diff --git a/in.go b/in.go new file mode 100644 index 0000000..4583c40 --- /dev/null +++ b/in.go @@ -0,0 +1,27 @@ +package validate + +import "errors" + +// In validates whether a value is found in a slice of allowed values. +func In[T comparable](allow []T) func(T) error { + return func(value T) error { + for _, cmp := range allow { + if cmp == value { + return nil + } + } + return errors.New("Not an allowed value") + } +} + +// NotIn validates whether a value is not found in a slice of disallowed values. +func NotIn[T comparable](allow []T) func(T) error { + return func(value T) error { + for _, cmp := range allow { + if cmp == value { + return errors.New("Not an allowed value") + } + } + return nil + } +} diff --git a/in_test.go b/in_test.go new file mode 100644 index 0000000..229bc1f --- /dev/null +++ b/in_test.go @@ -0,0 +1,69 @@ +package validate + +import ( + "fmt" + "strings" + "testing" +) + +func TestIn(t *testing.T) { + type TestCase[T comparable] struct { + S []T + Input T + Err bool + } + + strIn := []string{"abcd", "ef", "1234"} + strTestCases := []TestCase[string]{ + {S: strIn, Input: "abcd"}, + {S: strIn, Input: "ef"}, + {S: strIn, Input: "1234"}, + {S: strIn, Input: "5678", Err: true}, + } + + for _, tc := range strTestCases { + t.Logf("%q in %s", tc.Input, strings.Join(tc.S, ", ")) + + f := In(tc.S) + err := f(tc.Input) + + if tc.Err { + if err == nil { + t.Error("Expected error; got nil") + } + } else { + if err != nil { + t.Errorf("Expected nil; got %s", err) + } + } + } + + intIn := []int{1, 23, 456} + intTestCases := []TestCase[int]{ + {S: intIn, Input: 1}, + {S: intIn, Input: 23}, + {S: intIn, Input: 456}, + {S: intIn, Input: 789, Err: true}, + } + + for _, tc := range intTestCases { + intf := []string{} + for _, v := range tc.S { + intf = append(intf, fmt.Sprint(v)) + } + t.Logf("%d in %s", tc.Input, strings.Join(intf, ", ")) + + f := In(tc.S) + err := f(tc.Input) + + if tc.Err { + if err == nil { + t.Error("Expected error; got nil") + } + } else { + if err != nil { + t.Errorf("Expected nil; got %s", err) + } + } + } +}