-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidator.go
135 lines (118 loc) · 3.86 KB
/
validator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package valis
import "reflect"
type (
// Validator provides validation methods.
// And, each rule uses a validator to save the error details.
Validator struct {
commonRules []Rule
errorCollectorFactoryFunc ErrorCollectorFactoryFunc
loc *Location
errorCollector ErrorCollector
}
// CloneOpts is an option of Clone.
CloneOpts struct {
// When InheritLocation is true, Clone keeps the Location.
InheritLocation bool
// When InheritErrorCollector is true, Clone keeps the ErrorCollector.
InheritErrorCollector bool
// When Location is not nil and InheritLocation is false, Clone set the Location to the new Validator.
Location *Location
// When ErrorCollector is not nil and InheritErrorCollector is false, Clone set the ErrorCollector to the new Validator.
ErrorCollector ErrorCollector
}
)
// NewValidator returns a new Validator.
func NewValidator() *Validator {
v := &Validator{
errorCollectorFactoryFunc: func() ErrorCollector {
return NewStandardErrorCollector(DefaultLocationNameResolver)
},
loc: newRootLocation(),
}
return v
}
// SetCommonRules is update common rules.
func (v *Validator) SetCommonRules(rules ...Rule) {
v.commonRules = rules
}
// AddCommonRules add the rules to common rules.
func (v *Validator) AddCommonRules(rules ...Rule) {
v.commonRules = append(v.commonRules, rules...)
}
// SetErrorCollectorFactoryFunc is update ErrorCollectorFactoryFunc.
func (v *Validator) SetErrorCollectorFactoryFunc(f ErrorCollectorFactoryFunc) {
v.errorCollectorFactoryFunc = f
}
// Clone returns a new Validator inheriting the settings.
func (v *Validator) Clone(opts *CloneOpts) *Validator {
newValidator := *v
if opts.InheritErrorCollector {
newValidator.errorCollector = v.errorCollector
} else {
newValidator.errorCollector = opts.ErrorCollector
}
if !opts.InheritLocation {
if opts.Location != nil {
newValidator.loc = opts.Location
} else {
newValidator.loc = newRootLocation()
}
}
return &newValidator
}
// Location returns a current location.
func (v *Validator) Location() *Location {
return v.loc
}
// DiveField moves from the current position to the next location specified the field and performs validation processing.
// Do not use it outside of Rules.
func (v *Validator) DiveField(field *reflect.StructField, f func(v *Validator)) {
loc := v.loc
v.loc = loc.FieldLocation(field)
f(v)
v.loc = loc
}
// DiveIndex moves from the current position to the next location specified the index and performs validation processing.
// Do not use it outside of Rules.
func (v *Validator) DiveIndex(index int, f func(v *Validator)) {
loc := v.loc
v.loc = loc.IndexLocation(index)
f(v)
v.loc = loc
}
// DiveMapKey moves from the current position to the next location specified the key and performs validation processing.
// Do not use it outside of Rules.
func (v *Validator) DiveMapKey(key interface{}, f func(v *Validator)) {
loc := v.loc
v.loc = loc.MapKeyLocation(key)
f(v)
v.loc = loc
}
// DiveMapValue moves from the current position to the next location specified the key and performs validation processing.
// Do not use it outside of Rules.
func (v *Validator) DiveMapValue(key interface{}, f func(v *Validator)) {
loc := v.loc
v.loc = loc.MapValueLocation(key)
f(v)
v.loc = loc
}
// ErrorCollector returns an ErrorCollector.
func (v *Validator) ErrorCollector() ErrorCollector {
if v.errorCollector == nil {
v.errorCollector = v.errorCollectorFactoryFunc()
if v.errorCollector == nil {
panic("failed to create an ErrorCollector")
}
}
return v.errorCollector
}
// Validate the value.
// It returns an error if any rules are not met.
func (v *Validator) Validate(value interface{}, rules ...Rule) error {
newValidator := v.Clone(&CloneOpts{})
And(rules...).Validate(newValidator, value)
if newValidator.ErrorCollector().HasError() {
return newValidator.ErrorCollector().MakeError()
}
return nil
}