diff --git a/doc.go b/doc.go index 18efe3a..5485a8e 100644 --- a/doc.go +++ b/doc.go @@ -127,60 +127,80 @@ Here is a list of the current built in validators: Tells the validation to skip this struct field; this is particularily handy in ignoring embedded structs from being validated. (Usage: -) + | + This is the 'or' operator allowing multiple validators to be used and + accepted. (Usage: rbg|rgba) <-- this would allow either rgb or rgba + colors to be accepted. This can also be combined with 'and' for example + ( Usage: omitempty,rgb|rgba) + omitempty Allows conitional validation, for example if a field is not set with a value (Determined by the required validator) then other validation such as min or max won't run, but if a value is set validation will run. (Usage: omitempty) + required This validates that the value is not the data types default value. For numbers ensures value is not zero. For strings ensures value is not "". For slices, arrays, and maps, ensures the length is not zero. (Usage: required) + len For numbers, max will ensure that the value is equal to the parameter given. For strings, it checks that the string length is exactly that number of characters. For slices, arrays, and maps, validates the number of items. (Usage: len=10) + max For numbers, max will ensure that the value is less than or equal to the parameter given. For strings, it checks that the string length is at most that number of characters. For slices, arrays, and maps, validates the number of items. (Usage: max=10) + min For numbers, min will ensure that the value is greater or equal to the parameter given. For strings, it checks that the string length is at least that number of characters. For slices, arrays, and maps, validates the number of items. (Usage: min=10) + alpha This validates that a strings value contains alpha characters only (Usage: alpha) + alphanum This validates that a strings value contains alphanumeric characters only (Usage: alphanum) + numeric This validates that a strings value contains a basic numeric value. basic excludes exponents etc... (Usage: numeric) + hexadecimal This validates that a strings value contains a valid hexadecimal. (Usage: hexadecimal) + hexcolor This validates that a strings value contains a valid hex color including hashtag (#) (Usage: hexcolor) + rgb This validates that a strings value contains a valid rgb color (Usage: rgb) + rgba This validates that a strings value contains a valid rgba color (Usage: rgba) + hsl This validates that a strings value contains a valid hsl color (Usage: hsl) + hsla This validates that a strings value contains a valid hsla color (Usage: hsla) + email This validates that a strings value contains a valid email This may not conform to all possibilities of any rfc standard, but neither diff --git a/validator.go b/validator.go index 0386ae3..4b14f8b 100644 --- a/validator.go +++ b/validator.go @@ -288,35 +288,96 @@ func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag st for _, valTag := range valTags { - // TODO: validate = in regex's - vals := strings.Split(valTag, "=") - key := strings.Trim(vals[0], " ") + orVals := strings.Split(valTag, "|") - if len(key) == 0 { - panic(fmt.Sprintf("Invalid validation tag on field %s", name)) - } + if len(orVals) > 1 { - // OK to continue because we checked it's existance before getting into this loop - if key == omitempty { - continue - } + errTag := "" - valFunc, ok := v.validationFuncs[key] - if !ok { - panic(fmt.Sprintf("Undefined validation function on field %s", name)) - } + for _, val := range orVals { - param := "" - if len(vals) > 1 { - param = strings.Trim(vals[1], " ") - } + key, err := v.validateFieldByNameAndSingleTag(f, name, val) - if err := valFunc(f, param); !err { + if err == nil { + return nil + } - return errors.New(key) + errTag += "|" + key + + } + + errTag = strings.TrimLeft(errTag, "|") + + return errors.New(errTag) + } + + if _, err := v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil { + return err } + // TODO: validate = in regex's + // vals := strings.Split(valTag, "=") + // key := strings.Trim(vals[0], " ") + // + // if len(key) == 0 { + // panic(fmt.Sprintf("Invalid validation tag on field %s", name)) + // } + // + // // OK to continue because we checked it's existance before getting into this loop + // if key == omitempty { + // continue + // } + // + // valFunc, ok := v.validationFuncs[key] + // if !ok { + // panic(fmt.Sprintf("Undefined validation function on field %s", name)) + // } + // + // param := "" + // if len(vals) > 1 { + // param = strings.Trim(vals[1], " ") + // } + // + // if err := valFunc(f, param); !err { + // + // return errors.New(key) + // } + // if err := v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil { + // return err + // } + } return nil } + +func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string, valTag string) (string, error) { + + vals := strings.Split(valTag, "=") + key := strings.Trim(vals[0], " ") + + if len(key) == 0 { + panic(fmt.Sprintf("Invalid validation tag on field %s", name)) + } + + // OK to continue because we checked it's existance before getting into this loop + if key == omitempty { + return key, nil + } + + valFunc, ok := v.validationFuncs[key] + if !ok { + panic(fmt.Sprintf("Undefined validation function on field %s", name)) + } + + param := "" + if len(vals) > 1 { + param = strings.Trim(vals[1], " ") + } + + if err := valFunc(f, param); !err { + return key, errors.New(key) + } + + return key, nil +} diff --git a/validator_test.go b/validator_test.go index 1ec3874..e677dc0 100644 --- a/validator_test.go +++ b/validator_test.go @@ -113,6 +113,34 @@ func AssertMapFieldError(s map[string]*validator.FieldValidationError, field str c.Assert(val.ErrorTag, Equals, expectedTag) } +func (ms *MySuite) TestOrTag(c *C) { + s := "rgba(0,31,255,0.5)" + err := validator.ValidateFieldByTag(s, "rgb|rgba") + c.Assert(err, IsNil) + + s = "rgba(0,31,255,0.5)" + err = validator.ValidateFieldByTag(s, "rgb|rgba|len=18") + c.Assert(err, IsNil) + + s = "this ain't right" + err = validator.ValidateFieldByTag(s, "rgb|rgba") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "rgb|rgba") + + s = "this ain't right" + err = validator.ValidateFieldByTag(s, "rgb|rgba|len=10") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "rgb|rgba|len") + + s = "this is right" + err = validator.ValidateFieldByTag(s, "rgb|rgba|len=13") + c.Assert(err, IsNil) + + s = "" + err = validator.ValidateFieldByTag(s, "omitempty,rgb|rgba") + c.Assert(err, IsNil) +} + func (ms *MySuite) TestHsla(c *C) { s := "hsla(360,100%,100%,1)"