From cb4720cd31259371294f9407295793bee90e0f83 Mon Sep 17 00:00:00 2001 From: NiseVoid Date: Fri, 24 Apr 2020 12:36:13 +0200 Subject: [PATCH] Add not (!) to invert validation rules --- validate.go | 9 +++++++-- validate_test.go | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/validate.go b/validate.go index f1cc1aa..035d30c 100644 --- a/validate.go +++ b/validate.go @@ -206,10 +206,15 @@ func getTagFuncs(i int, ft reflect.StructField, kind reflect.Kind, tags []string continue } - check, val := getTagFunc(tag, value, kind) + var not bool + if strings.HasPrefix(tag, `!`) { + not = true + } + + check, val := getTagFunc(strings.TrimPrefix(tag, `!`), value, kind) f := func(rv reflect.Value) ([]ValidationError, bool) { - if check(rv, val) { + if check(rv, val) == !not { return nil, true } diff --git a/validate_test.go b/validate_test.go index 035b0b9..1e9b3b9 100644 --- a/validate_test.go +++ b/validate_test.go @@ -76,3 +76,24 @@ func TestValidationErrorField(t *testing.T) { t.Fatal(`Expected errors to be A.B.C[0].D and A.B.C[2].D; got`, errs[0].Field, `and`, errs[1].Field) } } + +func TestNot(t *testing.T) { + type s struct { + A string `validate:"!len=3"` + B int `validate:"!eq=3"` + } + + var pass1 = s{`ab`, 2} + var pass2 = s{`abcd`, 4} + + var fail = s{`abc`, 3} + + check(t, pass1, 0) + check(t, pass2, 0) + check(t, fail, 2) + + errs := Validate(fail) + if errs[0].Check != `!len` || errs[1].Check != `!eq` { + t.Errorf(`Checknames missing !, got "%s" and "%s"`, errs[0].Check, errs[1].Check) + } +}