From 94aa4243a20f0426f4551cac2db35c262ba81ef3 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Moal Date: Thu, 17 Oct 2019 19:41:40 +0200 Subject: [PATCH 1/2] Rework the non standard validators documentation --- doc.go | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/doc.go b/doc.go index e0396cb..500eed7 100644 --- a/doc.go +++ b/doc.go @@ -1058,27 +1058,14 @@ Validator notes: And the best reason, you can submit a pull request and we can keep on adding to the validation library of this package! -Panics - -This package panics when bad input is provided, this is by design, bad code like -that should not make it to production. - - type Test struct { - TestField string `validate:"nonexistantfunction=1"` - } - - t := &Test{ - TestField: "Test" - } - - validate.Struct(t) // this will panic - Non standard validators A collection of validation rules that are frequently needed but are more complex than the ones found in the baked in validators. -A non standard validator must be registered manually using any tag you like. -See below examples of registration and use. +A non standard validator must be registered manually like you would +with your own custom validation functions. + +Example of registration and use: type Test struct { TestField string `validate:"yourtag"` @@ -1089,7 +1076,9 @@ See below examples of registration and use. } validate := validator.New() - validate.RegisterValidation("yourtag", validations.ValidatorName) + validate.RegisterValidation("yourtag", validators.NotBlank) + +Here is a list of the current non standard validators: NotBlank This validates that the value is not blank or with length zero. @@ -1097,5 +1086,20 @@ See below examples of registration and use. ensures they don't have zero length. For others, a non empty value is required. Usage: notblank + +Panics + +This package panics when bad input is provided, this is by design, bad code like +that should not make it to production. + + type Test struct { + TestField string `validate:"nonexistantfunction=1"` + } + + t := &Test{ + TestField: "Test" + } + + validate.Struct(t) // this will panic */ package validator From c370ccf1ba9313593e886ed2c748ac5b5bd9a44c Mon Sep 17 00:00:00 2001 From: Jean-Philippe Moal Date: Thu, 17 Oct 2019 20:02:12 +0200 Subject: [PATCH 2/2] Clarify and complete tag names example --- _examples/simple/main.go | 4 ++-- _examples/struct-level/main.go | 27 +++++++++++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/_examples/simple/main.go b/_examples/simple/main.go index 459356d..55eb3cb 100644 --- a/_examples/simple/main.go +++ b/_examples/simple/main.go @@ -68,8 +68,8 @@ func validateStruct() { fmt.Println(err.Namespace()) fmt.Println(err.Field()) - fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or - fmt.Println(err.StructField()) // by passing alt name to ReportError like below + fmt.Println(err.StructNamespace()) + fmt.Println(err.StructField()) fmt.Println(err.Tag()) fmt.Println(err.ActualTag()) fmt.Println(err.Kind()) diff --git a/_examples/struct-level/main.go b/_examples/struct-level/main.go index 1c505e6..3b923f0 100644 --- a/_examples/struct-level/main.go +++ b/_examples/struct-level/main.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "reflect" + "strings" "gopkg.in/go-playground/validator.v9" ) @@ -11,7 +13,7 @@ type User struct { FirstName string `json:"fname"` LastName string `json:"lname"` Age uint8 `validate:"gte=0,lte=130"` - Email string `validate:"required,email"` + Email string `json:"e-mail" validate:"required,email"` FavouriteColor string `validate:"hexcolor|rgb|rgba"` Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage... } @@ -31,6 +33,15 @@ func main() { validate = validator.New() + // register function to get tag name from json tags. + validate.RegisterTagNameFunc(func(fld reflect.StructField) string { + name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] + if name == "-" { + return "" + } + return name + }) + // register validation for 'User' // NOTE: only have to register a non-pointer type for 'User', validator // interanlly dereferences during it's type checks. @@ -48,7 +59,7 @@ func main() { FirstName: "", LastName: "", Age: 45, - Email: "Badger.Smith@gmail.com", + Email: "Badger.Smith@gmail", FavouriteColor: "#000", Addresses: []*Address{address}, } @@ -67,10 +78,10 @@ func main() { for _, err := range err.(validator.ValidationErrors) { - fmt.Println(err.Namespace()) - fmt.Println(err.Field()) - fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or - fmt.Println(err.StructField()) // by passing alt name to ReportError like below + fmt.Println(err.Namespace()) // can differ when a custom TagNameFunc is registered or + fmt.Println(err.Field()) // by passing alt name to ReportError like below + fmt.Println(err.StructNamespace()) + fmt.Println(err.StructField()) fmt.Println(err.Tag()) fmt.Println(err.ActualTag()) fmt.Println(err.Kind()) @@ -101,8 +112,8 @@ func UserStructLevelValidation(sl validator.StructLevel) { user := sl.Current().Interface().(User) if len(user.FirstName) == 0 && len(user.LastName) == 0 { - sl.ReportError(user.FirstName, "FirstName", "fname", "fnameorlname", "") - sl.ReportError(user.LastName, "LastName", "lname", "fnameorlname", "") + sl.ReportError(user.FirstName, "fname", "FirstName", "fnameorlname", "") + sl.ReportError(user.LastName, "lname", "LastName", "fnameorlname", "") } // plus can do more, even with different tag than "fnameorlname"