@@ -78,6 +78,7 @@ func (s *tagCacheMap) Set(key string, value *cachedTag) {
7878// Validate contains the validator settings passed in using the Config struct
7979type Validate struct {
8080 tagName string
81+ fieldNameTag string
8182 validationFuncs map [string ]Func
8283 customTypeFuncs map [reflect.Type ]CustomTypeFunc
8384 aliasValidators map [string ]string
@@ -96,7 +97,8 @@ func (v *Validate) initCheck() {
9697// Config contains the options that a Validator instance will use.
9798// It is passed to the New() function
9899type Config struct {
99- TagName string
100+ TagName string
101+ FieldNameTag string
100102}
101103
102104// CustomTypeFunc allows for overriding or adding custom field type handler functions
@@ -137,6 +139,7 @@ func (ve ValidationErrors) Error() string {
137139// with other properties that may be needed for error message creation
138140type FieldError struct {
139141 Field string
142+ Name string
140143 Tag string
141144 ActualTag string
142145 Kind reflect.Kind
@@ -149,8 +152,9 @@ type FieldError struct {
149152func New (config * Config ) * Validate {
150153
151154 v := & Validate {
152- tagName : config .TagName ,
153- tagsCache : & tagCacheMap {m : map [string ]* cachedTag {}},
155+ tagName : config .TagName ,
156+ fieldNameTag : config .FieldNameTag ,
157+ tagsCache : & tagCacheMap {m : map [string ]* cachedTag {}},
154158 errsPool : & sync.Pool {New : func () interface {} {
155159 return ValidationErrors {}
156160 }}}
@@ -245,7 +249,7 @@ func (v *Validate) Field(field interface{}, tag string) error {
245249 errs := v .errsPool .Get ().(ValidationErrors )
246250 fieldVal := reflect .ValueOf (field )
247251
248- v .traverseField (fieldVal , fieldVal , fieldVal , blank , errs , false , tag , blank , false , false , nil )
252+ v .traverseField (fieldVal , fieldVal , fieldVal , blank , errs , false , tag , blank , blank , false , false , nil )
249253
250254 if len (errs ) == 0 {
251255 v .errsPool .Put (errs )
@@ -265,7 +269,7 @@ func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string
265269 errs := v .errsPool .Get ().(ValidationErrors )
266270 topVal := reflect .ValueOf (val )
267271
268- v .traverseField (topVal , topVal , reflect .ValueOf (field ), blank , errs , false , tag , blank , false , false , nil )
272+ v .traverseField (topVal , topVal , reflect .ValueOf (field ), blank , errs , false , tag , blank , blank , false , false , nil )
269273
270274 if len (errs ) == 0 {
271275 v .errsPool .Put (errs )
@@ -417,12 +421,20 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec
417421 }
418422 }
419423
420- v .traverseField (topStruct , currentStruct , current .Field (i ), errPrefix , errs , true , fld .Tag .Get (v .tagName ), fld .Name , partial , exclude , includeExclude )
424+ customName := fld .Name
425+ if v .fieldNameTag != "" {
426+ name := strings .Split (fld .Tag .Get (v .fieldNameTag ), "," )[0 ]
427+ if name != "" {
428+ customName = name
429+ }
430+ }
431+
432+ v .traverseField (topStruct , currentStruct , current .Field (i ), errPrefix , errs , true , fld .Tag .Get (v .tagName ), fld .Name , customName , partial , exclude , includeExclude )
421433 }
422434}
423435
424436// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options
425- func (v * Validate ) traverseField (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , errPrefix string , errs ValidationErrors , isStructField bool , tag string , name string , partial bool , exclude bool , includeExclude map [string ]* struct {}) {
437+ func (v * Validate ) traverseField (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , errPrefix string , errs ValidationErrors , isStructField bool , tag , name , customName string , partial bool , exclude bool , includeExclude map [string ]* struct {}) {
426438
427439 if tag == skipValidationTag {
428440 return
@@ -448,6 +460,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
448460
449461 if kind == reflect .Invalid {
450462 errs [errPrefix + name ] = & FieldError {
463+ Name : customName ,
451464 Field : name ,
452465 Tag : cTag .tags [0 ].tag ,
453466 ActualTag : cTag .tags [0 ].tagVals [0 ][0 ],
@@ -458,6 +471,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
458471 }
459472
460473 errs [errPrefix + name ] = & FieldError {
474+ Name : customName ,
461475 Field : name ,
462476 Tag : cTag .tags [0 ].tag ,
463477 ActualTag : cTag .tags [0 ].tagVals [0 ][0 ],
@@ -520,7 +534,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
520534 continue
521535 }
522536
523- if v .validateField (topStruct , currentStruct , current , typ , kind , errPrefix , errs , valTag , name ) {
537+ if v .validateField (topStruct , currentStruct , current , typ , kind , errPrefix , errs , valTag , name , customName ) {
524538 return
525539 }
526540 }
@@ -530,9 +544,9 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
530544 // or panic ;)
531545 switch kind {
532546 case reflect .Slice , reflect .Array :
533- v .traverseSlice (topStruct , currentStruct , current , errPrefix , errs , diveSubTag , name , partial , exclude , includeExclude )
547+ v .traverseSlice (topStruct , currentStruct , current , errPrefix , errs , diveSubTag , name , customName , partial , exclude , includeExclude )
534548 case reflect .Map :
535- v .traverseMap (topStruct , currentStruct , current , errPrefix , errs , diveSubTag , name , partial , exclude , includeExclude )
549+ v .traverseMap (topStruct , currentStruct , current , errPrefix , errs , diveSubTag , name , customName , partial , exclude , includeExclude )
536550 default :
537551 // throw error, if not a slice or map then should not have gotten here
538552 // bad dive tag
@@ -542,23 +556,23 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
542556}
543557
544558// traverseSlice traverses a Slice or Array's elements and passes them to traverseField for validation
545- func (v * Validate ) traverseSlice (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , errPrefix string , errs ValidationErrors , tag string , name string , partial bool , exclude bool , includeExclude map [string ]* struct {}) {
559+ func (v * Validate ) traverseSlice (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , errPrefix string , errs ValidationErrors , tag , name , customName string , partial bool , exclude bool , includeExclude map [string ]* struct {}) {
546560
547561 for i := 0 ; i < current .Len (); i ++ {
548- v .traverseField (topStruct , currentStruct , current .Index (i ), errPrefix , errs , false , tag , fmt .Sprintf (arrayIndexFieldName , name , i ), partial , exclude , includeExclude )
562+ v .traverseField (topStruct , currentStruct , current .Index (i ), errPrefix , errs , false , tag , fmt .Sprintf (arrayIndexFieldName , name , i ), fmt . Sprintf ( arrayIndexFieldName , customName , i ), partial , exclude , includeExclude )
549563 }
550564}
551565
552566// traverseMap traverses a map's elements and passes them to traverseField for validation
553- func (v * Validate ) traverseMap (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , errPrefix string , errs ValidationErrors , tag string , name string , partial bool , exclude bool , includeExclude map [string ]* struct {}) {
567+ func (v * Validate ) traverseMap (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , errPrefix string , errs ValidationErrors , tag , name , customName string , partial bool , exclude bool , includeExclude map [string ]* struct {}) {
554568
555569 for _ , key := range current .MapKeys () {
556- v .traverseField (topStruct , currentStruct , current .MapIndex (key ), errPrefix , errs , false , tag , fmt .Sprintf (mapIndexFieldName , name , key .Interface ()), partial , exclude , includeExclude )
570+ v .traverseField (topStruct , currentStruct , current .MapIndex (key ), errPrefix , errs , false , tag , fmt .Sprintf (mapIndexFieldName , name , key .Interface ()), fmt . Sprintf ( mapIndexFieldName , customName , key . Interface ()), partial , exclude , includeExclude )
557571 }
558572}
559573
560574// validateField validates a field based on the provided tag's key and param values and returns true if there is an error or false if all ok
561- func (v * Validate ) validateField (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , currentType reflect.Type , currentKind reflect.Kind , errPrefix string , errs ValidationErrors , valTag * tagVals , name string ) bool {
575+ func (v * Validate ) validateField (topStruct reflect.Value , currentStruct reflect.Value , current reflect.Value , currentType reflect.Type , currentKind reflect.Kind , errPrefix string , errs ValidationErrors , valTag * tagVals , name , customName string ) bool {
562576
563577 var valFunc Func
564578 var ok bool
@@ -583,6 +597,7 @@ func (v *Validate) validateField(topStruct reflect.Value, currentStruct reflect.
583597
584598 if valTag .isAlias {
585599 errs [errPrefix + name ] = & FieldError {
600+ Name : customName ,
586601 Field : name ,
587602 Tag : valTag .tag ,
588603 ActualTag : errTag [1 :],
@@ -592,6 +607,7 @@ func (v *Validate) validateField(topStruct reflect.Value, currentStruct reflect.
592607 }
593608 } else {
594609 errs [errPrefix + name ] = & FieldError {
610+ Name : customName ,
595611 Field : name ,
596612 Tag : errTag [1 :],
597613 ActualTag : errTag [1 :],
@@ -614,6 +630,7 @@ func (v *Validate) validateField(topStruct reflect.Value, currentStruct reflect.
614630 }
615631
616632 errs [errPrefix + name ] = & FieldError {
633+ Name : customName ,
617634 Field : name ,
618635 Tag : valTag .tag ,
619636 ActualTag : valTag .tagVals [0 ][0 ],
0 commit comments