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
 ================
 <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)
 [![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)
@@ -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
 -   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.
--   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
 ------------
@@ -56,11 +56,11 @@ Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usa
 
 ##### 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)
 
 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
 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
 

+ 20 - 2
field_level.go

@@ -16,6 +16,13 @@ type FieldLevel interface {
 	// returns current field for validation
 	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
 	Param() string
 
@@ -40,12 +47,23 @@ func (v *validate) Field() reflect.Value {
 	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
 func (v *validate) Param() string {
-	return v.flParam
+	return v.ct.param
 }
 
 // GetStructFieldOK returns Param returns param for validation against current field
 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
 	slCurrent    reflect.Value
 	flField      reflect.Value
-	flParam      string
 	fldIsPointer bool
+	cf           *cField
+	ct           *cTag
 
 	// misc reusable values
 	misc []byte
@@ -215,7 +216,8 @@ OUTER:
 			// set Field Level fields
 			v.slflParent = parent
 			v.flField = current
-			v.flParam = ""
+			v.cf = cf
+			v.ct = ct
 
 			if !v.fldIsPointer && !hasValue(v) {
 				return
@@ -309,7 +311,8 @@ OUTER:
 				// set Field Level fields
 				v.slflParent = parent
 				v.flField = current
-				v.flParam = ct.param
+				v.cf = cf
+				v.ct = ct
 
 				if ct.fn(v) {
 
@@ -397,7 +400,8 @@ OUTER:
 			// set Field Level fields
 			v.slflParent = parent
 			v.flField = current
-			v.flParam = ct.param
+			v.cf = cf
+			v.ct = ct
 
 			// // report error interface functions need these
 			// v.ns = ns

+ 66 - 0
validator_test.go

@@ -7013,3 +7013,69 @@ func TestMapStructNamespace(t *testing.T) {
 	Equal(t, len(ve), 1)
 	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")
+}