11package main
22
33import (
4+ "encoding/json"
45 "fmt"
56 "reflect"
67 "strings"
78
89 "github.com/go-playground/validator/v10"
910)
1011
12+ type validationError struct {
13+ Namespace string `json:"namespace"` // can differ when a custom TagNameFunc is registered or
14+ Field string `json:"field"` // by passing alt name to ReportError like below
15+ StructNamespace string `json:"structNamespace"`
16+ StructField string `json:"structField"`
17+ Tag string `json:"tag"`
18+ ActualTag string `json:"actualTag"`
19+ Kind string `json:"kind"`
20+ Type string `json:"type"`
21+ Value string `json:"value"`
22+ Param string `json:"param"`
23+ Message string `json:"message"`
24+ }
25+
26+ type Gender uint
27+
28+ const (
29+ Male Gender = iota + 1
30+ Female
31+ Intersex
32+ )
33+
34+ func (gender Gender ) String () string {
35+ terms := []string {"Male" , "Female" , "Intersex" }
36+ if gender < Male || gender > Intersex {
37+ return "unknown"
38+ }
39+ return terms [gender ]
40+ }
41+
1142// User contains user information
1243type User struct {
1344 FirstName string `json:"fname"`
@@ -16,6 +47,7 @@ type User struct {
1647 Email string `json:"e-mail" validate:"required,email"`
1748 FavouriteColor string `validate:"hexcolor|rgb|rgba"`
1849 Addresses []* Address `validate:"required,dive,required"` // a person can have a home and cottage...
50+ Gender Gender `json:"gender" validate:"required,gender_custom_validation"`
1951}
2052
2153// Address houses a users address information
@@ -47,6 +79,17 @@ func main() {
4779 // internally dereferences during it's type checks.
4880 validate .RegisterStructValidation (UserStructLevelValidation , User {})
4981
82+ // register a custom validation for user genre on a line
83+ // validates that an enum is within the interval
84+ err := validate .RegisterValidation ("gender_custom_validation" , func (fl validator.FieldLevel ) bool {
85+ value := fl .Field ().Interface ().(Gender )
86+ return value .String () != "unknown"
87+ })
88+ if err != nil {
89+ fmt .Println (err )
90+ return
91+ }
92+
5093 // build 'User' info, normally posted data etc...
5194 address := & Address {
5295 Street : "Eavesdown Docks" ,
@@ -65,7 +108,7 @@ func main() {
65108 }
66109
67110 // returns InvalidValidationError for bad validation input, nil or ValidationErrors ( []FieldError )
68- err : = validate .Struct (user )
111+ err = validate .Struct (user )
69112 if err != nil {
70113
71114 // this check is only needed when your code could produce
@@ -77,18 +120,27 @@ func main() {
77120 }
78121
79122 for _ , err := range err .(validator.ValidationErrors ) {
80-
81- fmt .Println (err .Namespace ()) // can differ when a custom TagNameFunc is registered or
82- fmt .Println (err .Field ()) // by passing alt name to ReportError like below
83- fmt .Println (err .StructNamespace ())
84- fmt .Println (err .StructField ())
85- fmt .Println (err .Tag ())
86- fmt .Println (err .ActualTag ())
87- fmt .Println (err .Kind ())
88- fmt .Println (err .Type ())
89- fmt .Println (err .Value ())
90- fmt .Println (err .Param ())
91- fmt .Println ()
123+ e := validationError {
124+ Namespace : err .Namespace (),
125+ Field : err .Field (),
126+ StructNamespace : err .StructNamespace (),
127+ StructField : err .StructField (),
128+ Tag : err .Tag (),
129+ ActualTag : err .ActualTag (),
130+ Kind : fmt .Sprintf ("%v" , err .Kind ()),
131+ Type : fmt .Sprintf ("%v" , err .Type ()),
132+ Value : fmt .Sprintf ("%v" , err .Value ()),
133+ Param : err .Param (),
134+ Message : err .Error (),
135+ }
136+
137+ indent , err := json .MarshalIndent (e , "" , " " )
138+ if err != nil {
139+ fmt .Println (err )
140+ panic (err )
141+ }
142+
143+ fmt .Println (string (indent ))
92144 }
93145
94146 // from here you can create your own error messages in whatever language you wish
0 commit comments