OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gopkg.in / go-playground / validator.v9 / struct_level.go
1 package validator
2
3 import (
4         "context"
5         "reflect"
6 )
7
8 // StructLevelFunc accepts all values needed for struct level validation
9 type StructLevelFunc func(sl StructLevel)
10
11 // StructLevelFuncCtx accepts all values needed for struct level validation
12 // but also allows passing of contextual validation information vi context.Context.
13 type StructLevelFuncCtx func(ctx context.Context, sl StructLevel)
14
15 // wrapStructLevelFunc wraps noramal StructLevelFunc makes it compatible with StructLevelFuncCtx
16 func wrapStructLevelFunc(fn StructLevelFunc) StructLevelFuncCtx {
17         return func(ctx context.Context, sl StructLevel) {
18                 fn(sl)
19         }
20 }
21
22 // StructLevel contains all the information and helper functions
23 // to validate a struct
24 type StructLevel interface {
25
26         // returns the main validation object, in case one want to call validations internally.
27         // this is so you don;t have to use anonymous functoins to get access to the validate
28         // instance.
29         Validator() *Validate
30
31         // returns the top level struct, if any
32         Top() reflect.Value
33
34         // returns the current fields parent struct, if any
35         Parent() reflect.Value
36
37         // returns the current struct.
38         Current() reflect.Value
39
40         // ExtractType gets the actual underlying type of field value.
41         // It will dive into pointers, customTypes and return you the
42         // underlying value and it's kind.
43         ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
44
45         // reports an error just by passing the field and tag information
46         //
47         // NOTES:
48         //
49         // fieldName and altName get appended to the existing namespace that
50         // validator is on. eg. pass 'FirstName' or 'Names[0]' depending
51         // on the nesting
52         //
53         // tag can be an existing validation tag or just something you make up
54         // and process on the flip side it's up to you.
55         ReportError(field interface{}, fieldName, structFieldName string, tag, param string)
56
57         // reports an error just by passing ValidationErrors
58         //
59         // NOTES:
60         //
61         // relativeNamespace and relativeActualNamespace get appended to the
62         // existing namespace that validator is on.
63         // eg. pass 'User.FirstName' or 'Users[0].FirstName' depending
64         // on the nesting. most of the time they will be blank, unless you validate
65         // at a level lower the the current field depth
66         ReportValidationErrors(relativeNamespace, relativeActualNamespace string, errs ValidationErrors)
67 }
68
69 var _ StructLevel = new(validate)
70
71 // Top returns the top level struct
72 //
73 // NOTE: this can be the same as the current struct being validated
74 // if not is a nested struct.
75 //
76 // this is only called when within Struct and Field Level validation and
77 // should not be relied upon for an acurate value otherwise.
78 func (v *validate) Top() reflect.Value {
79         return v.top
80 }
81
82 // Parent returns the current structs parent
83 //
84 // NOTE: this can be the same as the current struct being validated
85 // if not is a nested struct.
86 //
87 // this is only called when within Struct and Field Level validation and
88 // should not be relied upon for an acurate value otherwise.
89 func (v *validate) Parent() reflect.Value {
90         return v.slflParent
91 }
92
93 // Current returns the current struct.
94 func (v *validate) Current() reflect.Value {
95         return v.slCurrent
96 }
97
98 // Validator returns the main validation object, in case one want to call validations internally.
99 func (v *validate) Validator() *Validate {
100         return v.v
101 }
102
103 // ExtractType gets the actual underlying type of field value.
104 func (v *validate) ExtractType(field reflect.Value) (reflect.Value, reflect.Kind, bool) {
105         return v.extractTypeInternal(field, false)
106 }
107
108 // ReportError reports an error just by passing the field and tag information
109 func (v *validate) ReportError(field interface{}, fieldName, structFieldName, tag, param string) {
110
111         fv, kind, _ := v.extractTypeInternal(reflect.ValueOf(field), false)
112
113         if len(structFieldName) == 0 {
114                 structFieldName = fieldName
115         }
116
117         v.str1 = string(append(v.ns, fieldName...))
118
119         if v.v.hasTagNameFunc || fieldName != structFieldName {
120                 v.str2 = string(append(v.actualNs, structFieldName...))
121         } else {
122                 v.str2 = v.str1
123         }
124
125         if kind == reflect.Invalid {
126
127                 v.errs = append(v.errs,
128                         &fieldError{
129                                 v:              v.v,
130                                 tag:            tag,
131                                 actualTag:      tag,
132                                 ns:             v.str1,
133                                 structNs:       v.str2,
134                                 fieldLen:       uint8(len(fieldName)),
135                                 structfieldLen: uint8(len(structFieldName)),
136                                 param:          param,
137                                 kind:           kind,
138                         },
139                 )
140                 return
141         }
142
143         v.errs = append(v.errs,
144                 &fieldError{
145                         v:              v.v,
146                         tag:            tag,
147                         actualTag:      tag,
148                         ns:             v.str1,
149                         structNs:       v.str2,
150                         fieldLen:       uint8(len(fieldName)),
151                         structfieldLen: uint8(len(structFieldName)),
152                         value:          fv.Interface(),
153                         param:          param,
154                         kind:           kind,
155                         typ:            fv.Type(),
156                 },
157         )
158 }
159
160 // ReportValidationErrors reports ValidationErrors obtained from running validations within the Struct Level validation.
161 //
162 // NOTE: this function prepends the current namespace to the relative ones.
163 func (v *validate) ReportValidationErrors(relativeNamespace, relativeStructNamespace string, errs ValidationErrors) {
164
165         var err *fieldError
166
167         for i := 0; i < len(errs); i++ {
168
169                 err = errs[i].(*fieldError)
170                 err.ns = string(append(append(v.ns, relativeNamespace...), err.ns...))
171                 err.structNs = string(append(append(v.actualNs, relativeStructNamespace...), err.structNs...))
172
173                 v.errs = append(v.errs, err)
174         }
175 }