From fd059fe2f115037631ac570c97c121d66666c8c1 Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Fri, 22 May 2015 20:17:32 -0400 Subject: [PATCH 1/3] remove unnecessary carriage returns for #44 --- validator.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/validator.go b/validator.go index e787ffa..e6bc858 100644 --- a/validator.go +++ b/validator.go @@ -25,7 +25,7 @@ const ( tagKeySeparator = "=" structOnlyTag = "structonly" omitempty = "omitempty" - fieldErrMsg = "Field validation for \"%s\" failed on the \"%s\" tag\n" + fieldErrMsg = "Field validation for \"%s\" failed on the \"%s\" tag" structErrMsg = "Struct:%s\n" ) @@ -65,12 +65,14 @@ func (e *StructErrors) Error() string { for _, err := range e.Errors { buff.WriteString(err.Error()) + buff.WriteString("\n") } for _, err := range e.StructErrors { buff.WriteString(err.Error()) + buff.WriteString("\n\n") } - buff.WriteString("\n\n") + return buff.String() } From 9d18657e1fefd7c94a8a56180c1fec4ac72630ce Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Fri, 22 May 2015 20:22:18 -0400 Subject: [PATCH 2/3] remove extra carriage returns for #44 --- validator.go | 1 - 1 file changed, 1 deletion(-) diff --git a/validator.go b/validator.go index e6bc858..a37f1fe 100644 --- a/validator.go +++ b/validator.go @@ -70,7 +70,6 @@ func (e *StructErrors) Error() string { for _, err := range e.StructErrors { buff.WriteString(err.Error()) - buff.WriteString("\n\n") } return buff.String() From 3dcc019b648b87c4b0f2411f4ae20ba58a2a8e2d Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Fri, 22 May 2015 22:28:40 -0400 Subject: [PATCH 3/3] add contains, contains any, contains rune, excludes, excludes and excludesrune validation functions + tests + docuemtation for #43 --- baked_in.go | 94 ++++++++++++++++++++++++++++++++--------------- doc.go | 24 ++++++++++++ validator_test.go | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 30 deletions(-) diff --git a/baked_in.go b/baked_in.go index 8f3558e..ed69eb3 100644 --- a/baked_in.go +++ b/baked_in.go @@ -5,43 +5,77 @@ import ( "net/url" "reflect" "strconv" + "strings" "time" + "unicode/utf8" ) // BakedInValidators is the default map of ValidationFunc // you can add, remove or even replace items to suite your needs, // or even disregard and use your own map if so desired. var BakedInValidators = map[string]Func{ - "required": hasValue, - "len": hasLengthOf, - "min": hasMinOf, - "max": hasMaxOf, - "eq": isEq, - "ne": isNe, - "lt": isLt, - "lte": isLte, - "gt": isGt, - "gte": isGte, - "eqfield": isEqField, - "nefield": isNeField, - "gtefield": isGteField, - "gtfield": isGtField, - "ltefield": isLteField, - "ltfield": isLtField, - "alpha": isAlpha, - "alphanum": isAlphanum, - "numeric": isNumeric, - "number": isNumber, - "hexadecimal": isHexadecimal, - "hexcolor": isHexcolor, - "rgb": isRgb, - "rgba": isRgba, - "hsl": isHsl, - "hsla": isHsla, - "email": isEmail, - "url": isURL, - "uri": isURI, - "base64": isBase64, + "required": hasValue, + "len": hasLengthOf, + "min": hasMinOf, + "max": hasMaxOf, + "eq": isEq, + "ne": isNe, + "lt": isLt, + "lte": isLte, + "gt": isGt, + "gte": isGte, + "eqfield": isEqField, + "nefield": isNeField, + "gtefield": isGteField, + "gtfield": isGtField, + "ltefield": isLteField, + "ltfield": isLtField, + "alpha": isAlpha, + "alphanum": isAlphanum, + "numeric": isNumeric, + "number": isNumber, + "hexadecimal": isHexadecimal, + "hexcolor": isHexcolor, + "rgb": isRgb, + "rgba": isRgba, + "hsl": isHsl, + "hsla": isHsla, + "email": isEmail, + "url": isURL, + "uri": isURI, + "base64": isBase64, + "contains": contains, + "containsany": containsAny, + "containsrune": containsRune, + "excludes": excludes, + "excludesall": excludesAll, + "excludesrune": excludesRune, +} + +func excludesRune(top interface{}, current interface{}, field interface{}, param string) bool { + return !containsRune(top, current, field, param) +} + +func excludesAll(top interface{}, current interface{}, field interface{}, param string) bool { + return !containsAny(top, current, field, param) +} + +func excludes(top interface{}, current interface{}, field interface{}, param string) bool { + return !contains(top, current, field, param) +} + +func containsRune(top interface{}, current interface{}, field interface{}, param string) bool { + r, _ := utf8.DecodeRuneInString(param) + + return strings.ContainsRune(field.(string), r) +} + +func containsAny(top interface{}, current interface{}, field interface{}, param string) bool { + return strings.ContainsAny(field.(string), param) +} + +func contains(top interface{}, current interface{}, field interface{}, param string) bool { + return strings.Contains(field.(string), param) } func isNeField(top interface{}, current interface{}, field interface{}, param string) bool { diff --git a/doc.go b/doc.go index dfbece5..1b02c0f 100644 --- a/doc.go +++ b/doc.go @@ -333,6 +333,30 @@ Here is a list of the current built in validators: as an error, if you wish to accept an empty string as valid you can use this with the omitempty tag. (Usage: base64) + contains + This validates that a string value contains the substring value. + (Usage: contains=@) + + containsany + This validates that a string value contains any Unicode code points + in the substring value. (Usage: containsany=!@#?) + + containsrune + This validates that a string value contains the supplied rune value. + (Usage: containsrune=@) + + excludes + This validates that a string value does not contain the substring value. + (Usage: excludes=@) + + excludesall + This validates that a string value does not contain any Unicode code + points in the substring value. (Usage: excludesall=!@#?) + + excludesrune + This validates that a string value does not contain the supplied rune value. + (Usage: excludesrune=@) + Validator notes: regex diff --git a/validator_test.go b/validator_test.go index 6544fd0..e5f2de5 100644 --- a/validator_test.go +++ b/validator_test.go @@ -142,6 +142,76 @@ func isEqualFunc(val interface{}, current interface{}, field interface{}, param return current.(string) == field.(string) } +func (ms *MySuite) TestExcludesRuneValidation(c *C) { + + s := "a☺b☻c☹d" + s2 := "abcd" + + err := validate.Field(s, "excludesrune=☻") + c.Assert(err, NotNil) + + err = validate.Field(s2, "excludesrune=☻") + c.Assert(err, IsNil) +} + +func (ms *MySuite) TestExcludesAllValidation(c *C) { + + s := "abcd@!jfk" + s2 := "abcdefg" + + err := validate.Field(s, "excludesall=@!{}[]") + c.Assert(err, NotNil) + + err = validate.Field(s2, "excludesall=@!{}[]") + c.Assert(err, IsNil) +} + +func (ms *MySuite) TestExcludesValidation(c *C) { + + s := "abcd@!jfk" + + err := validate.Field(s, "excludes=@") + c.Assert(err, NotNil) + + err = validate.Field(s, "excludes=q") + c.Assert(err, IsNil) +} + +func (ms *MySuite) TestContainsRuneValidation(c *C) { + + s := "a☺b☻c☹d" + s2 := "abcd" + + err := validate.Field(s, "containsrune=☻") + c.Assert(err, IsNil) + + err = validate.Field(s2, "containsrune=☻") + c.Assert(err, NotNil) +} + +func (ms *MySuite) TestContainsAnyValidation(c *C) { + + s := "abcd@!jfk" + s2 := "abcdefg" + + err := validate.Field(s, "containsany=@!{}[]") + c.Assert(err, IsNil) + + err = validate.Field(s2, "containsany=@!{}[]") + c.Assert(err, NotNil) +} + +func (ms *MySuite) TestContainsValidation(c *C) { + + s := "abcd@!jfk" + + err := validate.Field(s, "contains=@") + c.Assert(err, IsNil) + + err = validate.Field(s, "contains=q") + c.Assert(err, NotNil) +} + func (ms *MySuite) TestIsNeFieldValidation(c *C) { var j uint64