Add Access to Field Name from FieldLevel (#284)

pull/285/head v9.4.0
Dean Karn 8 years ago committed by GitHub
parent 27158c7a84
commit fb68f39656
  1. 14
      README.md
  2. 0
      _examples/custom/main.go
  3. 0
      _examples/gin-upgrading-overriding/main.go
  4. 0
      _examples/gin-upgrading-overriding/v8_to_v9.go
  5. 0
      _examples/simple/main.go
  6. 0
      _examples/struct-level/main.go
  7. 0
      _examples/translations/main.go
  8. 2
      doc.go
  9. 22
      field_level.go
  10. 12
      validator.go
  11. 66
      validator_test.go

@ -1,7 +1,7 @@
Package validator Package validator
================ ================
<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) <img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![Project status](https://img.shields.io/badge/version-9.3.6-green.svg) ![Project status](https://img.shields.io/badge/version-9.4.0-green.svg)
[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/validator/branches/v9/badge.svg)](https://semaphoreci.com/joeybloggs/validator) [![Build Status](https://semaphoreci.com/api/v1/joeybloggs/validator/branches/v9/badge.svg)](https://semaphoreci.com/joeybloggs/validator)
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v9&service=github)](https://coveralls.io/github/go-playground/validator?branch=v9) [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v9&service=github)](https://coveralls.io/github/go-playground/validator?branch=v9)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@ -19,7 +19,7 @@ It has the following **unique** features:
- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs - Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError - Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
- Customizable i18n aware error messages. - Customizable i18n aware error messages.
- Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/v9/examples/gin-upgrading-overriding) - Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
Installation Installation
------------ ------------
@ -56,11 +56,11 @@ Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usa
##### Examples: ##### Examples:
- [Simple](https://github.com/go-playground/validator/blob/v9/examples/simple/main.go) - [Simple](https://github.com/go-playground/validator/blob/v9/_examples/simple/main.go)
- [Custom Field Types](https://github.com/go-playground/validator/blob/v9/examples/custom/main.go) - [Custom Field Types](https://github.com/go-playground/validator/blob/v9/_examples/custom/main.go)
- [Struct Level](https://github.com/go-playground/validator/blob/v9/examples/struct-level/main.go) - [Struct Level](https://github.com/go-playground/validator/blob/v9/_examples/struct-level/main.go)
- [Translations & Custom Errors](https://github.com/go-playground/validator/blob/v9/examples/translations/main.go) - [Translations & Custom Errors](https://github.com/go-playground/validator/blob/v9/_examples/translations/main.go)
- [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/examples/gin-upgrading-overriding) - [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
- [wash - an example application putting it all together](https://github.com/bluesuncorp/wash) - [wash - an example application putting it all together](https://github.com/bluesuncorp/wash)
Benchmarks Benchmarks

@ -5,7 +5,7 @@ based on tags.
It can also handle Cross-Field and Cross-Struct validation for nested structs It can also handle Cross-Field and Cross-Struct validation for nested structs
and has the ability to dive into arrays and maps of any type. and has the ability to dive into arrays and maps of any type.
see more examples https://github.com/go-playground/validator/tree/v9/examples see more examples https://github.com/go-playground/validator/tree/v9/_examples
Validation Functions Return Type error Validation Functions Return Type error

@ -16,6 +16,13 @@ type FieldLevel interface {
// returns current field for validation // returns current field for validation
Field() reflect.Value Field() reflect.Value
// returns the field's name with the tag
// name takeing precedence over the fields actual name.
FieldName() string
// returns the struct field's name
StructFieldName() string
// returns param for validation against current field // returns param for validation against current field
Param() string Param() string
@ -40,12 +47,23 @@ func (v *validate) Field() reflect.Value {
return v.flField return v.flField
} }
// FieldName returns the field's name with the tag
// name takeing precedence over the fields actual name.
func (v *validate) FieldName() string {
return v.cf.altName
}
// StructFieldName returns the struct field's name
func (v *validate) StructFieldName() string {
return v.cf.name
}
// Param returns param for validation against current field // Param returns param for validation against current field
func (v *validate) Param() string { func (v *validate) Param() string {
return v.flParam return v.ct.param
} }
// GetStructFieldOK returns Param returns param for validation against current field // GetStructFieldOK returns Param returns param for validation against current field
func (v *validate) GetStructFieldOK() (reflect.Value, reflect.Kind, bool) { func (v *validate) GetStructFieldOK() (reflect.Value, reflect.Kind, bool) {
return v.getStructFieldOKInternal(v.slflParent, v.flParam) return v.getStructFieldOKInternal(v.slflParent, v.ct.param)
} }

@ -23,8 +23,9 @@ type validate struct {
slflParent reflect.Value slflParent reflect.Value
slCurrent reflect.Value slCurrent reflect.Value
flField reflect.Value flField reflect.Value
flParam string
fldIsPointer bool fldIsPointer bool
cf *cField
ct *cTag
// misc reusable values // misc reusable values
misc []byte misc []byte
@ -215,7 +216,8 @@ OUTER:
// set Field Level fields // set Field Level fields
v.slflParent = parent v.slflParent = parent
v.flField = current v.flField = current
v.flParam = "" v.cf = cf
v.ct = ct
if !v.fldIsPointer && !hasValue(v) { if !v.fldIsPointer && !hasValue(v) {
return return
@ -309,7 +311,8 @@ OUTER:
// set Field Level fields // set Field Level fields
v.slflParent = parent v.slflParent = parent
v.flField = current v.flField = current
v.flParam = ct.param v.cf = cf
v.ct = ct
if ct.fn(v) { if ct.fn(v) {
@ -397,7 +400,8 @@ OUTER:
// set Field Level fields // set Field Level fields
v.slflParent = parent v.slflParent = parent
v.flField = current v.flField = current
v.flParam = ct.param v.cf = cf
v.ct = ct
// // report error interface functions need these // // report error interface functions need these
// v.ns = ns // v.ns = ns

@ -7013,3 +7013,69 @@ func TestMapStructNamespace(t *testing.T) {
Equal(t, len(ve), 1) Equal(t, len(ve), 1)
AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required") AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
} }
func TestFieldLevelName(t *testing.T) {
type Test struct {
String string `validate:"custom1" json:"json1"`
Array []string `validate:"dive,custom2" json:"json2"`
Map map[string]string `validate:"dive,custom3" json:"json3"`
Array2 []string `validate:"custom4" json:"json4"`
Map2 map[string]string `validate:"custom5" json:"json5"`
}
var res1, res2, res3, res4, res5, alt1, alt2, alt3, alt4, alt5 string
validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
validate.RegisterValidation("custom1", func(fl FieldLevel) bool {
res1 = fl.FieldName()
alt1 = fl.StructFieldName()
return true
})
validate.RegisterValidation("custom2", func(fl FieldLevel) bool {
res2 = fl.FieldName()
alt2 = fl.StructFieldName()
return true
})
validate.RegisterValidation("custom3", func(fl FieldLevel) bool {
res3 = fl.FieldName()
alt3 = fl.StructFieldName()
return true
})
validate.RegisterValidation("custom4", func(fl FieldLevel) bool {
res4 = fl.FieldName()
alt4 = fl.StructFieldName()
return true
})
validate.RegisterValidation("custom5", func(fl FieldLevel) bool {
res5 = fl.FieldName()
alt5 = fl.StructFieldName()
return true
})
test := Test{
String: "test",
Array: []string{"1"},
Map: map[string]string{"test": "test"},
}
errs := validate.Struct(test)
Equal(t, errs, nil)
Equal(t, res1, "json1")
Equal(t, alt1, "String")
Equal(t, res2, "json2[0]")
Equal(t, alt2, "Array[0]")
Equal(t, res3, "json3[test]")
Equal(t, alt3, "Map[test]")
Equal(t, res4, "json4")
Equal(t, alt4, "Array2")
Equal(t, res5, "json5")
Equal(t, alt5, "Map2")
}

Loading…
Cancel
Save