Skip to content

Commit 0f02c73

Browse files
Dean KarnDean Karn
authored andcommitted
Merge branch 'v1' into v1-development
2 parents 6c26ed7 + ac82433 commit 0f02c73

File tree

3 files changed

+87
-97
lines changed

3 files changed

+87
-97
lines changed

doc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ but you may also create a new instance if needed.
88
99
// built in
1010
errs := validator.ValidateStruct(//your struct)
11-
errs := validator.ValidateFieldByTag(field, "omitempty,min=1,max=10")
11+
valErr := validator.ValidateFieldByTag(field, "omitempty,min=1,max=10")
1212
1313
// new
1414
newValidator = validator.New("struct tag name", validator.BakedInFunctions)
@@ -57,7 +57,7 @@ intended use is for development + debugging, not a production error message.
5757
5858
Why not a better error message? because this library intends for you to handle your own error messages
5959
60-
Why should I handle my own errors? Many reasons, for me building and internationalized application
60+
Why should I handle my own errors? Many reasons, for me building an internationalized application
6161
I needed to know the field and what validation failed so that I could provide an error in the users specific language.
6262
6363
if fieldErr.Field == "Name" {

validator.go

Lines changed: 30 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ const (
2727
type FieldValidationError struct {
2828
Field string
2929
ErrorTag string
30+
Kind reflect.Kind
31+
Param string
32+
Value interface{}
3033
}
3134

3235
// This is intended for use in development + debugging and not intended to be a production error message.
@@ -220,7 +223,7 @@ func (v *Validator) ValidateStruct(s interface{}) *StructValidationErrors {
220223

221224
default:
222225

223-
if fieldError := v.validateStructFieldByTag(valueField.Interface(), typeField.Name, tag); fieldError != nil {
226+
if fieldError := v.validateFieldByNameAndTag(valueField.Interface(), typeField.Name, tag); fieldError != nil {
224227
validationErrors.Errors[fieldError.Field] = fieldError
225228
// free up memory reference
226229
fieldError = nil
@@ -235,32 +238,19 @@ func (v *Validator) ValidateStruct(s interface{}) *StructValidationErrors {
235238
return validationErrors
236239
}
237240

238-
// ValidateFieldWithTag validates the given field by the given tag arguments
239-
func (v *Validator) validateStructFieldByTag(f interface{}, name string, tag string) *FieldValidationError {
240-
241-
if err := v.validateFieldByNameAndTag(f, name, tag); err != nil {
242-
return &FieldValidationError{
243-
Field: name,
244-
ErrorTag: err.Error(),
245-
}
246-
}
247-
248-
return nil
249-
}
250-
251241
// ValidateFieldByTag allows validation of a single field with the internal validator, still using tag style validation to check multiple errors
252-
func ValidateFieldByTag(f interface{}, tag string) error {
242+
func ValidateFieldByTag(f interface{}, tag string) *FieldValidationError {
253243

254244
return internalValidator.validateFieldByNameAndTag(f, "", tag)
255245
}
256246

257247
// ValidateFieldByTag allows validation of a single field, still using tag style validation to check multiple errors
258-
func (v *Validator) ValidateFieldByTag(f interface{}, tag string) error {
248+
func (v *Validator) ValidateFieldByTag(f interface{}, tag string) *FieldValidationError {
259249

260250
return v.validateFieldByNameAndTag(f, "", tag)
261251
}
262252

263-
func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag string) error {
253+
func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag string) *FieldValidationError {
264254

265255
// This is a double check if coming from ValidateStruct but need to be here in case function is called directly
266256
if tag == "-" {
@@ -283,7 +273,8 @@ func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag st
283273
panic("Invalid field passed to ValidateFieldWithTag")
284274
}
285275

286-
// TODO: validate commas in regex's
276+
var valErr *FieldValidationError
277+
var err error
287278
valTags := strings.Split(tag, ",")
288279

289280
for _, valTag := range valTags {
@@ -296,62 +287,35 @@ func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag st
296287

297288
for _, val := range orVals {
298289

299-
key, err := v.validateFieldByNameAndSingleTag(f, name, val)
290+
valErr, err = v.validateFieldByNameAndSingleTag(f, name, val)
300291

301292
if err == nil {
302293
return nil
303294
}
304295

305-
errTag += "|" + key
296+
errTag += "|" + valErr.ErrorTag
306297

307298
}
308299

309300
errTag = strings.TrimLeft(errTag, "|")
310301

311-
return errors.New(errTag)
312-
}
302+
valErr.ErrorTag = errTag
303+
valErr.Kind = valueField.Kind()
313304

314-
if _, err := v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil {
315-
return err
305+
return valErr
316306
}
317307

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-
// }
308+
if valErr, err = v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil {
309+
valErr.Kind = valueField.Kind()
348310

311+
return valErr
312+
}
349313
}
350314

351315
return nil
352316
}
353317

354-
func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string, valTag string) (string, error) {
318+
func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string, valTag string) (*FieldValidationError, error) {
355319

356320
vals := strings.Split(valTag, "=")
357321
key := strings.Trim(vals[0], " ")
@@ -360,9 +324,16 @@ func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string,
360324
panic(fmt.Sprintf("Invalid validation tag on field %s", name))
361325
}
362326

327+
valErr := &FieldValidationError{
328+
Field: name,
329+
ErrorTag: key,
330+
Value: f,
331+
Param: "",
332+
}
333+
363334
// OK to continue because we checked it's existance before getting into this loop
364335
if key == omitempty {
365-
return key, nil
336+
return valErr, nil
366337
}
367338

368339
valFunc, ok := v.validationFuncs[key]
@@ -376,8 +347,9 @@ func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string,
376347
}
377348

378349
if err := valFunc(f, param); !err {
379-
return key, errors.New(key)
350+
valErr.Param = param
351+
return valErr, errors.New(key)
380352
}
381353

382-
return key, nil
354+
return valErr, nil
383355
}

0 commit comments

Comments
 (0)