Skip to content

Commit 87fff1c

Browse files
Dean KarnDean Karn
authored andcommitted
Merge branch 'v1-development' into v1
2 parents 74deae7 + cc1ba6a commit 87fff1c

File tree

3 files changed

+129
-20
lines changed

3 files changed

+129
-20
lines changed

doc.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,60 +127,80 @@ Here is a list of the current built in validators:
127127
Tells the validation to skip this struct field; this is particularily
128128
handy in ignoring embedded structs from being validated. (Usage: -)
129129
130+
|
131+
This is the 'or' operator allowing multiple validators to be used and
132+
accepted. (Usage: rbg|rgba) <-- this would allow either rgb or rgba
133+
colors to be accepted. This can also be combined with 'and' for example
134+
( Usage: omitempty,rgb|rgba)
135+
130136
omitempty
131137
Allows conitional validation, for example if a field is not set with
132138
a value (Determined by the required validator) then other validation
133139
such as min or max won't run, but if a value is set validation will run.
134140
(Usage: omitempty)
141+
135142
required
136143
This validates that the value is not the data types default value.
137144
For numbers ensures value is not zero. For strings ensures value is
138145
not "". For slices, arrays, and maps, ensures the length is not zero.
139146
(Usage: required)
147+
140148
len
141149
For numbers, max will ensure that the value is
142150
equal to the parameter given. For strings, it checks that
143151
the string length is exactly that number of characters. For slices,
144152
arrays, and maps, validates the number of items. (Usage: len=10)
153+
145154
max
146155
For numbers, max will ensure that the value is
147156
less than or equal to the parameter given. For strings, it checks
148157
that the string length is at most that number of characters. For
149158
slices, arrays, and maps, validates the number of items. (Usage: max=10)
159+
150160
min
151161
For numbers, min will ensure that the value is
152162
greater or equal to the parameter given. For strings, it checks that
153163
the string length is at least that number of characters. For slices,
154164
arrays, and maps, validates the number of items. (Usage: min=10)
165+
155166
alpha
156167
This validates that a strings value contains alpha characters only
157168
(Usage: alpha)
169+
158170
alphanum
159171
This validates that a strings value contains alphanumeric characters only
160172
(Usage: alphanum)
173+
161174
numeric
162175
This validates that a strings value contains a basic numeric value.
163176
basic excludes exponents etc...
164177
(Usage: numeric)
178+
165179
hexadecimal
166180
This validates that a strings value contains a valid hexadecimal.
167181
(Usage: hexadecimal)
182+
168183
hexcolor
169184
This validates that a strings value contains a valid hex color including
170185
hashtag (#)
171186
(Usage: hexcolor)
187+
172188
rgb
173189
This validates that a strings value contains a valid rgb color
174190
(Usage: rgb)
191+
175192
rgba
176193
This validates that a strings value contains a valid rgba color
177194
(Usage: rgba)
195+
178196
hsl
179197
This validates that a strings value contains a valid hsl color
180198
(Usage: hsl)
199+
181200
hsla
182201
This validates that a strings value contains a valid hsla color
183202
(Usage: hsla)
203+
184204
email
185205
This validates that a strings value contains a valid email
186206
This may not conform to all possibilities of any rfc standard, but neither

validator.go

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -288,35 +288,96 @@ func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag st
288288

289289
for _, valTag := range valTags {
290290

291-
// TODO: validate = in regex's
292-
vals := strings.Split(valTag, "=")
293-
key := strings.Trim(vals[0], " ")
291+
orVals := strings.Split(valTag, "|")
294292

295-
if len(key) == 0 {
296-
panic(fmt.Sprintf("Invalid validation tag on field %s", name))
297-
}
293+
if len(orVals) > 1 {
298294

299-
// OK to continue because we checked it's existance before getting into this loop
300-
if key == omitempty {
301-
continue
302-
}
295+
errTag := ""
303296

304-
valFunc, ok := v.validationFuncs[key]
305-
if !ok {
306-
panic(fmt.Sprintf("Undefined validation function on field %s", name))
307-
}
297+
for _, val := range orVals {
308298

309-
param := ""
310-
if len(vals) > 1 {
311-
param = strings.Trim(vals[1], " ")
312-
}
299+
key, err := v.validateFieldByNameAndSingleTag(f, name, val)
313300

314-
if err := valFunc(f, param); !err {
301+
if err == nil {
302+
return nil
303+
}
315304

316-
return errors.New(key)
305+
errTag += "|" + key
306+
307+
}
308+
309+
errTag = strings.TrimLeft(errTag, "|")
310+
311+
return errors.New(errTag)
312+
}
313+
314+
if _, err := v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil {
315+
return err
317316
}
318317

318+
// TODO: validate = in regex's
319+
// vals := strings.Split(valTag, "=")
320+
// key := strings.Trim(vals[0], " ")
321+
//
322+
// if len(key) == 0 {
323+
// panic(fmt.Sprintf("Invalid validation tag on field %s", name))
324+
// }
325+
//
326+
// // OK to continue because we checked it's existance before getting into this loop
327+
// if key == omitempty {
328+
// continue
329+
// }
330+
//
331+
// valFunc, ok := v.validationFuncs[key]
332+
// if !ok {
333+
// panic(fmt.Sprintf("Undefined validation function on field %s", name))
334+
// }
335+
//
336+
// param := ""
337+
// if len(vals) > 1 {
338+
// param = strings.Trim(vals[1], " ")
339+
// }
340+
//
341+
// if err := valFunc(f, param); !err {
342+
//
343+
// return errors.New(key)
344+
// }
345+
// if err := v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil {
346+
// return err
347+
// }
348+
319349
}
320350

321351
return nil
322352
}
353+
354+
func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string, valTag string) (string, error) {
355+
356+
vals := strings.Split(valTag, "=")
357+
key := strings.Trim(vals[0], " ")
358+
359+
if len(key) == 0 {
360+
panic(fmt.Sprintf("Invalid validation tag on field %s", name))
361+
}
362+
363+
// OK to continue because we checked it's existance before getting into this loop
364+
if key == omitempty {
365+
return key, nil
366+
}
367+
368+
valFunc, ok := v.validationFuncs[key]
369+
if !ok {
370+
panic(fmt.Sprintf("Undefined validation function on field %s", name))
371+
}
372+
373+
param := ""
374+
if len(vals) > 1 {
375+
param = strings.Trim(vals[1], " ")
376+
}
377+
378+
if err := valFunc(f, param); !err {
379+
return key, errors.New(key)
380+
}
381+
382+
return key, nil
383+
}

validator_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,34 @@ func AssertMapFieldError(s map[string]*validator.FieldValidationError, field str
113113
c.Assert(val.ErrorTag, Equals, expectedTag)
114114
}
115115

116+
func (ms *MySuite) TestOrTag(c *C) {
117+
s := "rgba(0,31,255,0.5)"
118+
err := validator.ValidateFieldByTag(s, "rgb|rgba")
119+
c.Assert(err, IsNil)
120+
121+
s = "rgba(0,31,255,0.5)"
122+
err = validator.ValidateFieldByTag(s, "rgb|rgba|len=18")
123+
c.Assert(err, IsNil)
124+
125+
s = "this ain't right"
126+
err = validator.ValidateFieldByTag(s, "rgb|rgba")
127+
c.Assert(err, NotNil)
128+
c.Assert(err.Error(), Equals, "rgb|rgba")
129+
130+
s = "this ain't right"
131+
err = validator.ValidateFieldByTag(s, "rgb|rgba|len=10")
132+
c.Assert(err, NotNil)
133+
c.Assert(err.Error(), Equals, "rgb|rgba|len")
134+
135+
s = "this is right"
136+
err = validator.ValidateFieldByTag(s, "rgb|rgba|len=13")
137+
c.Assert(err, IsNil)
138+
139+
s = ""
140+
err = validator.ValidateFieldByTag(s, "omitempty,rgb|rgba")
141+
c.Assert(err, IsNil)
142+
}
143+
116144
func (ms *MySuite) TestHsla(c *C) {
117145

118146
s := "hsla(360,100%,100%,1)"

0 commit comments

Comments
 (0)