OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gopkg.in / go-playground / validator.v9 / _examples / struct-level / main.go
1 package main
2
3 import (
4         "fmt"
5
6         "gopkg.in/go-playground/validator.v9"
7 )
8
9 // User contains user information
10 type User struct {
11         FirstName      string     `json:"fname"`
12         LastName       string     `json:"lname"`
13         Age            uint8      `validate:"gte=0,lte=130"`
14         Email          string     `validate:"required,email"`
15         FavouriteColor string     `validate:"hexcolor|rgb|rgba"`
16         Addresses      []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
17 }
18
19 // Address houses a users address information
20 type Address struct {
21         Street string `validate:"required"`
22         City   string `validate:"required"`
23         Planet string `validate:"required"`
24         Phone  string `validate:"required"`
25 }
26
27 // use a single instance of Validate, it caches struct info
28 var validate *validator.Validate
29
30 func main() {
31
32         validate = validator.New()
33
34         // register validation for 'User'
35         // NOTE: only have to register a non-pointer type for 'User', validator
36         // interanlly dereferences during it's type checks.
37         validate.RegisterStructValidation(UserStructLevelValidation, User{})
38
39         // build 'User' info, normally posted data etc...
40         address := &Address{
41                 Street: "Eavesdown Docks",
42                 Planet: "Persphone",
43                 Phone:  "none",
44                 City:   "Unknown",
45         }
46
47         user := &User{
48                 FirstName:      "",
49                 LastName:       "",
50                 Age:            45,
51                 Email:          "Badger.Smith@gmail.com",
52                 FavouriteColor: "#000",
53                 Addresses:      []*Address{address},
54         }
55
56         // returns InvalidValidationError for bad validation input, nil or ValidationErrors ( []FieldError )
57         err := validate.Struct(user)
58         if err != nil {
59
60                 // this check is only needed when your code could produce
61                 // an invalid value for validation such as interface with nil
62                 // value most including myself do not usually have code like this.
63                 if _, ok := err.(*validator.InvalidValidationError); ok {
64                         fmt.Println(err)
65                         return
66                 }
67
68                 for _, err := range err.(validator.ValidationErrors) {
69
70                         fmt.Println(err.Namespace())
71                         fmt.Println(err.Field())
72                         fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or
73                         fmt.Println(err.StructField())     // by passing alt name to ReportError like below
74                         fmt.Println(err.Tag())
75                         fmt.Println(err.ActualTag())
76                         fmt.Println(err.Kind())
77                         fmt.Println(err.Type())
78                         fmt.Println(err.Value())
79                         fmt.Println(err.Param())
80                         fmt.Println()
81                 }
82
83                 // from here you can create your own error messages in whatever language you wish
84                 return
85         }
86
87         // save user to database
88 }
89
90 // UserStructLevelValidation contains custom struct level validations that don't always
91 // make sense at the field validation level. For Example this function validates that either
92 // FirstName or LastName exist; could have done that with a custom field validation but then
93 // would have had to add it to both fields duplicating the logic + overhead, this way it's
94 // only validated once.
95 //
96 // NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way
97 // hooks right into validator and you can combine with validation tags and still have a
98 // common error output format.
99 func UserStructLevelValidation(sl validator.StructLevel) {
100
101         user := sl.Current().Interface().(User)
102
103         if len(user.FirstName) == 0 && len(user.LastName) == 0 {
104                 sl.ReportError(user.FirstName, "FirstName", "fname", "fnameorlname", "")
105                 sl.ReportError(user.LastName, "LastName", "lname", "fnameorlname", "")
106         }
107
108         // plus can to more, even with different tag than "fnameorlname"
109 }