add ‘or’ operator to allow multiple validators to be used instead of
just the implicit ‘and’
pull/16/head
Dean Karn 10 years ago
parent be02036f69
commit cbf8124403
  1. 20
      doc.go
  2. 101
      validator.go
  3. 28
      validator_test.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

@ -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
}

@ -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)"

Loading…
Cancel
Save