Codebase list golang-github-go-playground-validator-v10 / 50d47f3
Merge branch 'v4' into v4-development Conflicts: doc.go Dean Karn 9 years ago
5 changed file(s) with 185 addition(s) and 172 deletion(s). Raw diff Collapse all Expand all
00 Package go-validate-yourself
11 ================
2 [![Build Status](https://travis-ci.org/joeybloggs/go-validate-yourself.svg?branch=v4-development)](https://travis-ci.org/joeybloggs/go-validate-yourself)
2 [![Build Status](https://travis-ci.org/joeybloggs/go-validate-yourself.svg?branch=v4)](https://travis-ci.org/joeybloggs/go-validate-yourself)
3 [![GoDoc](https://godoc.org/gopkg.in/joeybloggs/go-validate-yourself.v4?status.svg)](https://godoc.org/gopkg.in/joeybloggs/go-validate-yourself.v4)
34
45 Package validator implements value validations for structs and individual fields based on tags.
56
2122 Usage
2223 =====
2324
24 Please see http://godoc.org/gopkg.in/joeybloggs/go-validate-yourself.v3 for detailed usage docs.
25 Please see http://godoc.org/gopkg.in/joeybloggs/go-validate-yourself.v4 for detailed usage docs.
2526
2627 Contributing
2728 ============
3536
3637 I strongly encourage everyone whom creates a custom validation function to contribute them and
3738 help make this package even better.
39
40 License
41 =======
42 Distributed under MIT License, please see license file in code for more details.
3737 "uri": isURI,
3838 }
3939
40 func isURI(val interface{}, field interface{}, param string) bool {
40 func isURI(top interface{}, current interface{}, field interface{}, param string) bool {
4141
4242 st := reflect.ValueOf(field)
4343
5252 panic(fmt.Sprintf("Bad field type %T", field))
5353 }
5454
55 func isURL(val interface{}, field interface{}, param string) bool {
55 func isURL(top interface{}, current interface{}, field interface{}, param string) bool {
5656
5757 st := reflect.ValueOf(field)
5858
7575 panic(fmt.Sprintf("Bad field type %T", field))
7676 }
7777
78 func isEmail(val interface{}, field interface{}, param string) bool {
78 func isEmail(top interface{}, current interface{}, field interface{}, param string) bool {
7979
8080 st := reflect.ValueOf(field)
8181
8888 panic(fmt.Sprintf("Bad field type %T", field))
8989 }
9090
91 func isHsla(val interface{}, field interface{}, param string) bool {
91 func isHsla(top interface{}, current interface{}, field interface{}, param string) bool {
9292
9393 st := reflect.ValueOf(field)
9494
101101 panic(fmt.Sprintf("Bad field type %T", field))
102102 }
103103
104 func isHsl(val interface{}, field interface{}, param string) bool {
104 func isHsl(top interface{}, current interface{}, field interface{}, param string) bool {
105105
106106 st := reflect.ValueOf(field)
107107
114114 panic(fmt.Sprintf("Bad field type %T", field))
115115 }
116116
117 func isRgba(val interface{}, field interface{}, param string) bool {
117 func isRgba(top interface{}, current interface{}, field interface{}, param string) bool {
118118
119119 st := reflect.ValueOf(field)
120120
127127 panic(fmt.Sprintf("Bad field type %T", field))
128128 }
129129
130 func isRgb(val interface{}, field interface{}, param string) bool {
130 func isRgb(top interface{}, current interface{}, field interface{}, param string) bool {
131131
132132 st := reflect.ValueOf(field)
133133
140140 panic(fmt.Sprintf("Bad field type %T", field))
141141 }
142142
143 func isHexcolor(val interface{}, field interface{}, param string) bool {
143 func isHexcolor(top interface{}, current interface{}, field interface{}, param string) bool {
144144
145145 st := reflect.ValueOf(field)
146146
153153 panic(fmt.Sprintf("Bad field type %T", field))
154154 }
155155
156 func isHexadecimal(val interface{}, field interface{}, param string) bool {
156 func isHexadecimal(top interface{}, current interface{}, field interface{}, param string) bool {
157157
158158 st := reflect.ValueOf(field)
159159
166166 panic(fmt.Sprintf("Bad field type %T", field))
167167 }
168168
169 func isNumber(val interface{}, field interface{}, param string) bool {
169 func isNumber(top interface{}, current interface{}, field interface{}, param string) bool {
170170
171171 st := reflect.ValueOf(field)
172172
179179 panic(fmt.Sprintf("Bad field type %T", field))
180180 }
181181
182 func isNumeric(val interface{}, field interface{}, param string) bool {
182 func isNumeric(top interface{}, current interface{}, field interface{}, param string) bool {
183183
184184 st := reflect.ValueOf(field)
185185
192192 panic(fmt.Sprintf("Bad field type %T", field))
193193 }
194194
195 func isAlphanum(val interface{}, field interface{}, param string) bool {
195 func isAlphanum(top interface{}, current interface{}, field interface{}, param string) bool {
196196
197197 st := reflect.ValueOf(field)
198198
205205 panic(fmt.Sprintf("Bad field type %T", field))
206206 }
207207
208 func isAlpha(val interface{}, field interface{}, param string) bool {
208 func isAlpha(top interface{}, current interface{}, field interface{}, param string) bool {
209209
210210 st := reflect.ValueOf(field)
211211
218218 panic(fmt.Sprintf("Bad field type %T", field))
219219 }
220220
221 func hasValue(val interface{}, field interface{}, param string) bool {
221 func hasValue(top interface{}, current interface{}, field interface{}, param string) bool {
222222
223223 st := reflect.ValueOf(field)
224224
232232 }
233233 }
234234
235 func isGteField(val interface{}, field interface{}, param string) bool {
236
237 if val == nil {
235 func isGteField(top interface{}, current interface{}, field interface{}, param string) bool {
236
237 if current == nil {
238238 panic("struct not passed for cross validation")
239239 }
240240
241 topVal := reflect.ValueOf(val)
242
243 if topVal.Kind() == reflect.Ptr && !topVal.IsNil() {
244 topVal = reflect.ValueOf(topVal.Elem().Interface())
245 }
246
247 var topFieldVal reflect.Value
248
249 switch topVal.Kind() {
250
251 case reflect.Struct:
252
253 if topVal.Type() == reflect.TypeOf(time.Time{}) {
254 topFieldVal = topVal
241 currentVal := reflect.ValueOf(current)
242
243 if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
244 currentVal = reflect.ValueOf(currentVal.Elem().Interface())
245 }
246
247 var currentFielVal reflect.Value
248
249 switch currentVal.Kind() {
250
251 case reflect.Struct:
252
253 if currentVal.Type() == reflect.TypeOf(time.Time{}) {
254 currentFielVal = currentVal
255255 break
256256 }
257257
258 f := topVal.FieldByName(param)
258 f := currentVal.FieldByName(param)
259259
260260 if f.Kind() == reflect.Invalid {
261261 panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
262262 }
263263
264 topFieldVal = f
264 currentFielVal = f
265265
266266 default:
267267
268 topFieldVal = topVal
269 }
270
271 if topFieldVal.Kind() == reflect.Ptr && !topFieldVal.IsNil() {
272
273 topFieldVal = reflect.ValueOf(topFieldVal.Elem().Interface())
268 currentFielVal = currentVal
269 }
270
271 if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
272
273 currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
274274 }
275275
276276 fv := reflect.ValueOf(field)
279279
280280 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
281281
282 return fv.Int() >= topFieldVal.Int()
282 return fv.Int() >= currentFielVal.Int()
283283
284284 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
285285
286 return fv.Uint() >= topFieldVal.Uint()
286 return fv.Uint() >= currentFielVal.Uint()
287287
288288 case reflect.Float32, reflect.Float64:
289289
290 return fv.Float() >= topFieldVal.Float()
290 return fv.Float() >= currentFielVal.Float()
291291
292292 case reflect.Struct:
293293
294294 if fv.Type() == reflect.TypeOf(time.Time{}) {
295295
296 if topFieldVal.Type() != reflect.TypeOf(time.Time{}) {
296 if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
297297 panic("Bad Top Level field type")
298298 }
299299
300 t := topFieldVal.Interface().(time.Time)
300 t := currentFielVal.Interface().(time.Time)
301301 fieldTime := field.(time.Time)
302302
303303 return fieldTime.After(t) || fieldTime.Equal(t)
307307 panic(fmt.Sprintf("Bad field type %T", field))
308308 }
309309
310 func isGtField(val interface{}, field interface{}, param string) bool {
311
312 if val == nil {
310 func isGtField(top interface{}, current interface{}, field interface{}, param string) bool {
311
312 if current == nil {
313313 panic("struct not passed for cross validation")
314314 }
315315
316 topVal := reflect.ValueOf(val)
317
318 if topVal.Kind() == reflect.Ptr && !topVal.IsNil() {
319 topVal = reflect.ValueOf(topVal.Elem().Interface())
320 }
321
322 var topFieldVal reflect.Value
323
324 switch topVal.Kind() {
325
326 case reflect.Struct:
327
328 if topVal.Type() == reflect.TypeOf(time.Time{}) {
329 topFieldVal = topVal
316 currentVal := reflect.ValueOf(current)
317
318 if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
319 currentVal = reflect.ValueOf(currentVal.Elem().Interface())
320 }
321
322 var currentFielVal reflect.Value
323
324 switch currentVal.Kind() {
325
326 case reflect.Struct:
327
328 if currentVal.Type() == reflect.TypeOf(time.Time{}) {
329 currentFielVal = currentVal
330330 break
331331 }
332332
333 f := topVal.FieldByName(param)
333 f := currentVal.FieldByName(param)
334334
335335 if f.Kind() == reflect.Invalid {
336336 panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
337337 }
338338
339 topFieldVal = f
339 currentFielVal = f
340340
341341 default:
342342
343 topFieldVal = topVal
344 }
345
346 if topFieldVal.Kind() == reflect.Ptr && !topFieldVal.IsNil() {
347
348 topFieldVal = reflect.ValueOf(topFieldVal.Elem().Interface())
343 currentFielVal = currentVal
344 }
345
346 if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
347
348 currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
349349 }
350350
351351 fv := reflect.ValueOf(field)
354354
355355 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
356356
357 return fv.Int() > topFieldVal.Int()
357 return fv.Int() > currentFielVal.Int()
358358
359359 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
360360
361 return fv.Uint() > topFieldVal.Uint()
361 return fv.Uint() > currentFielVal.Uint()
362362
363363 case reflect.Float32, reflect.Float64:
364364
365 return fv.Float() > topFieldVal.Float()
365 return fv.Float() > currentFielVal.Float()
366366
367367 case reflect.Struct:
368368
369369 if fv.Type() == reflect.TypeOf(time.Time{}) {
370370
371 if topFieldVal.Type() != reflect.TypeOf(time.Time{}) {
371 if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
372372 panic("Bad Top Level field type")
373373 }
374374
375 t := topFieldVal.Interface().(time.Time)
375 t := currentFielVal.Interface().(time.Time)
376376 fieldTime := field.(time.Time)
377377
378378 return fieldTime.After(t)
382382 panic(fmt.Sprintf("Bad field type %T", field))
383383 }
384384
385 func isGte(val interface{}, field interface{}, param string) bool {
385 func isGte(top interface{}, current interface{}, field interface{}, param string) bool {
386386
387387 st := reflect.ValueOf(field)
388388
427427 panic(fmt.Sprintf("Bad field type %T", field))
428428 }
429429
430 func isGt(val interface{}, field interface{}, param string) bool {
430 func isGt(top interface{}, current interface{}, field interface{}, param string) bool {
431431
432432 st := reflect.ValueOf(field)
433433
471471 // length tests whether a variable's length is equal to a given
472472 // value. For strings it tests the number of characters whereas
473473 // for maps and slices it tests the number of items.
474 func hasLengthOf(val interface{}, field interface{}, param string) bool {
474 func hasLengthOf(top interface{}, current interface{}, field interface{}, param string) bool {
475475
476476 st := reflect.ValueOf(field)
477477
510510 // number. For number types, it's a simple lesser-than test; for
511511 // strings it tests the number of characters whereas for maps
512512 // and slices it tests the number of items.
513 func hasMinOf(val interface{}, field interface{}, param string) bool {
514
515 return isGte(val, field, param)
516 }
517
518 func isLteField(val interface{}, field interface{}, param string) bool {
519
520 if val == nil {
513 func hasMinOf(top interface{}, current interface{}, field interface{}, param string) bool {
514
515 return isGte(top, current, field, param)
516 }
517
518 func isLteField(top interface{}, current interface{}, field interface{}, param string) bool {
519
520 if current == nil {
521521 panic("struct not passed for cross validation")
522522 }
523523
524 topVal := reflect.ValueOf(val)
525
526 if topVal.Kind() == reflect.Ptr && !topVal.IsNil() {
527 topVal = reflect.ValueOf(topVal.Elem().Interface())
528 }
529
530 var topFieldVal reflect.Value
531
532 switch topVal.Kind() {
533
534 case reflect.Struct:
535
536 if topVal.Type() == reflect.TypeOf(time.Time{}) {
537 topFieldVal = topVal
524 currentVal := reflect.ValueOf(current)
525
526 if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
527 currentVal = reflect.ValueOf(currentVal.Elem().Interface())
528 }
529
530 var currentFielVal reflect.Value
531
532 switch currentVal.Kind() {
533
534 case reflect.Struct:
535
536 if currentVal.Type() == reflect.TypeOf(time.Time{}) {
537 currentFielVal = currentVal
538538 break
539539 }
540540
541 f := topVal.FieldByName(param)
541 f := currentVal.FieldByName(param)
542542
543543 if f.Kind() == reflect.Invalid {
544544 panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
545545 }
546546
547 topFieldVal = f
547 currentFielVal = f
548548
549549 default:
550550
551 topFieldVal = topVal
552 }
553
554 if topFieldVal.Kind() == reflect.Ptr && !topFieldVal.IsNil() {
555
556 topFieldVal = reflect.ValueOf(topFieldVal.Elem().Interface())
551 currentFielVal = currentVal
552 }
553
554 if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
555
556 currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
557557 }
558558
559559 fv := reflect.ValueOf(field)
562562
563563 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
564564
565 return fv.Int() <= topFieldVal.Int()
565 return fv.Int() <= currentFielVal.Int()
566566
567567 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
568568
569 return fv.Uint() <= topFieldVal.Uint()
569 return fv.Uint() <= currentFielVal.Uint()
570570
571571 case reflect.Float32, reflect.Float64:
572572
573 return fv.Float() <= topFieldVal.Float()
573 return fv.Float() <= currentFielVal.Float()
574574
575575 case reflect.Struct:
576576
577577 if fv.Type() == reflect.TypeOf(time.Time{}) {
578578
579 if topFieldVal.Type() != reflect.TypeOf(time.Time{}) {
579 if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
580580 panic("Bad Top Level field type")
581581 }
582582
583 t := topFieldVal.Interface().(time.Time)
583 t := currentFielVal.Interface().(time.Time)
584584 fieldTime := field.(time.Time)
585585
586586 return fieldTime.Before(t) || fieldTime.Equal(t)
590590 panic(fmt.Sprintf("Bad field type %T", field))
591591 }
592592
593 func isLtField(val interface{}, field interface{}, param string) bool {
594
595 if val == nil {
593 func isLtField(top interface{}, current interface{}, field interface{}, param string) bool {
594
595 if current == nil {
596596 panic("struct not passed for cross validation")
597597 }
598598
599 topVal := reflect.ValueOf(val)
600
601 if topVal.Kind() == reflect.Ptr && !topVal.IsNil() {
602 topVal = reflect.ValueOf(topVal.Elem().Interface())
603 }
604
605 var topFieldVal reflect.Value
606
607 switch topVal.Kind() {
608
609 case reflect.Struct:
610
611 if topVal.Type() == reflect.TypeOf(time.Time{}) {
612 topFieldVal = topVal
599 currentVal := reflect.ValueOf(current)
600
601 if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
602 currentVal = reflect.ValueOf(currentVal.Elem().Interface())
603 }
604
605 var currentFielVal reflect.Value
606
607 switch currentVal.Kind() {
608
609 case reflect.Struct:
610
611 if currentVal.Type() == reflect.TypeOf(time.Time{}) {
612 currentFielVal = currentVal
613613 break
614614 }
615615
616 f := topVal.FieldByName(param)
616 f := currentVal.FieldByName(param)
617617
618618 if f.Kind() == reflect.Invalid {
619619 panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
620620 }
621621
622 topFieldVal = f
622 currentFielVal = f
623623
624624 default:
625625
626 topFieldVal = topVal
627 }
628
629 if topFieldVal.Kind() == reflect.Ptr && !topFieldVal.IsNil() {
630
631 topFieldVal = reflect.ValueOf(topFieldVal.Elem().Interface())
626 currentFielVal = currentVal
627 }
628
629 if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
630
631 currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
632632 }
633633
634634 fv := reflect.ValueOf(field)
637637
638638 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
639639
640 return fv.Int() < topFieldVal.Int()
640 return fv.Int() < currentFielVal.Int()
641641
642642 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
643643
644 return fv.Uint() < topFieldVal.Uint()
644 return fv.Uint() < currentFielVal.Uint()
645645
646646 case reflect.Float32, reflect.Float64:
647647
648 return fv.Float() < topFieldVal.Float()
648 return fv.Float() < currentFielVal.Float()
649649
650650 case reflect.Struct:
651651
652652 if fv.Type() == reflect.TypeOf(time.Time{}) {
653653
654 if topFieldVal.Type() != reflect.TypeOf(time.Time{}) {
654 if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
655655 panic("Bad Top Level field type")
656656 }
657657
658 t := topFieldVal.Interface().(time.Time)
658 t := currentFielVal.Interface().(time.Time)
659659 fieldTime := field.(time.Time)
660660
661661 return fieldTime.Before(t)
665665 panic(fmt.Sprintf("Bad field type %T", field))
666666 }
667667
668 func isLte(val interface{}, field interface{}, param string) bool {
668 func isLte(top interface{}, current interface{}, field interface{}, param string) bool {
669669
670670 st := reflect.ValueOf(field)
671671
710710 panic(fmt.Sprintf("Bad field type %T", field))
711711 }
712712
713 func isLt(val interface{}, field interface{}, param string) bool {
713 func isLt(top interface{}, current interface{}, field interface{}, param string) bool {
714714
715715 st := reflect.ValueOf(field)
716716
756756 // value. For numbers, it's a simple lesser-than test; for
757757 // strings it tests the number of characters whereas for maps
758758 // and slices it tests the number of items.
759 func hasMaxOf(val interface{}, field interface{}, param string) bool {
760
761 return isLte(val, field, param)
759 func hasMaxOf(top interface{}, current interface{}, field interface{}, param string) bool {
760
761 return isLte(top, current, field, param)
762762 }
763763
764764 // asInt retuns the parameter as a int64
7878 Custom functions can be added
7979
8080 //Structure
81 func customFunc(val interface{}, field interface{}, param string) bool {
81 func customFunc(top interface{}, current interface{}, field interface{}, param string) bool {
8282
8383 if whatever {
8484 return false
136136 // this definition of min max will never validate
137137
138138 Baked In Validators and Tags
139
140 NOTE: Baked In Cross field validation only compares fields on the same struct,
141 if cross field + cross struct validation is needed your own custom validator
142 should be implemented.
139143
140144 Here is a list of the current built in validators:
141145
100100 return errs
101101 }
102102
103 // ValidationFunc that accepts a value(optional usage), a field and parameter(optional usage) for use in validation
104 type ValidationFunc func(val interface{}, v interface{}, param string) bool
103 // ValidationFunc accepts all values needed for file and cross field validation
104 // top = top level struct when validating by struct otherwise nil
105 // current = current level struct when validating by struct otherwise optional comparison value
106 // f = field value for validation
107 // param = parameter used in validation i.e. gt=0 param would be 0
108 type ValidationFunc func(top interface{}, current interface{}, f interface{}, param string) bool
105109
106110 // Validator implements the Validator Struct
107111 // NOTE: Fields within are not thread safe and that is on purpose
152156 // ValidateStruct validates a struct and returns a struct containing the errors
153157 func (v *Validator) ValidateStruct(s interface{}) *StructValidationErrors {
154158
155 return v.validateStructRecursive(s, s)
159 return v.validateStructRecursive(s, s, s)
156160 }
157161
158162 // validateStructRecursive validates a struct recursivly and passes the top level struct around for use in validator functions and returns a struct containing the errors
159 func (v *Validator) validateStructRecursive(top interface{}, s interface{}) *StructValidationErrors {
163 func (v *Validator) validateStructRecursive(top interface{}, current interface{}, s interface{}) *StructValidationErrors {
160164
161165 structValue := reflect.ValueOf(s)
162166 structType := reflect.TypeOf(s)
169173 }
170174
171175 if structValue.Kind() == reflect.Ptr && !structValue.IsNil() {
172 return v.validateStructRecursive(top, structValue.Elem().Interface())
176 return v.validateStructRecursive(top, current, structValue.Elem().Interface())
173177 }
174178
175179 if structValue.Kind() != reflect.Struct && structValue.Kind() != reflect.Interface {
208212
209213 if valueField.Type() == reflect.TypeOf(time.Time{}) {
210214
211 if fieldError := v.validateFieldByNameAndTagAndValue(top, valueField.Interface(), typeField.Name, tag); fieldError != nil {
215 if fieldError := v.validateFieldByNameAndTagAndValue(top, current, valueField.Interface(), typeField.Name, tag); fieldError != nil {
212216 validationErrors.Errors[fieldError.Field] = fieldError
213217 // free up memory reference
214218 fieldError = nil
220224 continue
221225 }
222226
223 if structErrors := v.validateStructRecursive(top, valueField.Interface()); structErrors != nil {
227 if structErrors := v.validateStructRecursive(top, valueField.Interface(), valueField.Interface()); structErrors != nil {
224228 validationErrors.StructErrors[typeField.Name] = structErrors
225229 // free up memory map no longer needed
226230 structErrors = nil
229233
230234 default:
231235
232 if fieldError := v.validateFieldByNameAndTagAndValue(top, valueField.Interface(), typeField.Name, tag); fieldError != nil {
236 if fieldError := v.validateFieldByNameAndTagAndValue(top, current, valueField.Interface(), typeField.Name, tag); fieldError != nil {
233237 validationErrors.Errors[fieldError.Field] = fieldError
234238 // free up memory reference
235239 fieldError = nil
253257 // ValidateFieldByTagAndValue allows validation of a single field, still using tag style validation to check multiple errors
254258 func (v *Validator) ValidateFieldByTagAndValue(val interface{}, f interface{}, tag string) *FieldValidationError {
255259
256 return v.validateFieldByNameAndTagAndValue(val, f, "", tag)
257 }
258
259 func (v *Validator) validateFieldByNameAndTagAndValue(val interface{}, f interface{}, name string, tag string) *FieldValidationError {
260 return v.validateFieldByNameAndTagAndValue(nil, val, f, "", tag)
261 }
262
263 func (v *Validator) validateFieldByNameAndTagAndValue(val interface{}, current interface{}, f interface{}, name string, tag string) *FieldValidationError {
260264
261265 // This is a double check if coming from ValidateStruct but need to be here in case function is called directly
262266 if tag == noValidationTag {
263267 return nil
264268 }
265269
266 if strings.Contains(tag, omitempty) && !hasValue(val, f, "") {
270 if strings.Contains(tag, omitempty) && !hasValue(val, current, f, "") {
267271 return nil
268272 }
269273
271275 fieldKind := valueField.Kind()
272276
273277 if fieldKind == reflect.Ptr && !valueField.IsNil() {
274 return v.validateFieldByNameAndTagAndValue(val, valueField.Elem().Interface(), name, tag)
278 return v.validateFieldByNameAndTagAndValue(val, current, valueField.Elem().Interface(), name, tag)
275279 }
276280
277281 fieldType := valueField.Type()
299303
300304 for _, val := range orVals {
301305
302 valErr, err = v.validateFieldByNameAndSingleTag(val, f, name, val)
306 valErr, err = v.validateFieldByNameAndSingleTag(val, current, f, name, val)
303307
304308 if err == nil {
305309 return nil
317321 return valErr
318322 }
319323
320 if valErr, err = v.validateFieldByNameAndSingleTag(val, f, name, valTag); err != nil {
324 if valErr, err = v.validateFieldByNameAndSingleTag(val, current, f, name, valTag); err != nil {
321325
322326 valErr.Kind = valueField.Kind()
323327 valErr.Type = fieldType
329333 return nil
330334 }
331335
332 func (v *Validator) validateFieldByNameAndSingleTag(val interface{}, f interface{}, name string, valTag string) (*FieldValidationError, error) {
336 func (v *Validator) validateFieldByNameAndSingleTag(val interface{}, current interface{}, f interface{}, name string, valTag string) (*FieldValidationError, error) {
333337
334338 vals := strings.Split(valTag, tagKeySeparator)
335339 key := strings.Trim(vals[0], " ")
360364 param = strings.Trim(vals[1], " ")
361365 }
362366
363 if err := valFunc(val, f, param); !err {
367 if err := valFunc(val, current, f, param); !err {
364368 valErr.Param = param
365369 return valErr, errors.New(key)
366370 }
126126 c.Assert(val.ErrorTag, Equals, expectedTag)
127127 }
128128
129 func newValidatorFunc(val interface{}, field interface{}, param string) bool {
129 func newValidatorFunc(val interface{}, current interface{}, field interface{}, param string) bool {
130130
131131 return true
132132 }
133133
134 func isEqualFunc(val interface{}, field interface{}, param string) bool {
135
136 return val.(string) == field.(string)
134 func isEqualFunc(val interface{}, current interface{}, field interface{}, param string) bool {
135
136 return current.(string) == field.(string)
137137 }
138138
139139 func (ms *MySuite) TestStructOnlyValidation(c *C) {