Sfoglia il codice sorgente

Add Access to Field Name from FieldLevel (#284)

Dean Karn 8 anni fa
parent
commit
fb68f39656

+ 7 - 7
README.md

@@ -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)
-- [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)
-- [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)
+- [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)
+- [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)
+- [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

+ 0 - 0
examples/custom/main.go → _examples/custom/main.go


+ 0 - 0
examples/gin-upgrading-overriding/main.go → _examples/gin-upgrading-overriding/main.go


+ 0 - 0
examples/gin-upgrading-overriding/v8_to_v9.go → _examples/gin-upgrading-overriding/v8_to_v9.go


+ 0 - 0
examples/simple/main.go → _examples/simple/main.go


+ 0 - 0
examples/struct-level/main.go → _examples/struct-level/main.go


+ 0 - 0
examples/translations/main.go → _examples/translations/main.go


+ 1 - 1
doc.go

@@ -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
 
 

+ 20 - 2
field_level.go

@@ -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)
 }
 }

+ 8 - 4
validator.go

@@ -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

+ 66 - 0
validator_test.go

@@ -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")
+}