Passed
Push — main ( 08e96c...9065c5 )
by Igor
01:14 queued 11s
created

validation.NilBoolProperty   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 3
dl 0
loc 2
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
package validation
2
3
import (
4
	"fmt"
5
	"time"
6
7
	"github.com/muonsoft/validation/generic"
8
	"golang.org/x/text/language"
9
)
10
11
// Argument used to set up the validation process. It is used to set up the current validation scope and to pass
12
// arguments for validation values.
13
type Argument interface {
14
	set(arguments *Arguments) error
15
}
16
17
type argumentFunc func(arguments *Arguments) error
18
19
func (f argumentFunc) set(arguments *Arguments) error {
20 1
	return f(arguments)
21
}
22
23
type Arguments struct {
24
	scope      Scope
25
	validators []validateFunc
26
}
27
28
func (args *Arguments) addValidator(validator validateFunc) {
29 1
	args.validators = append(args.validators, validator)
30
}
31
32
// Value argument is used to validate any supported value. It uses reflection to detect the type of the argument
33
// and pass it to a specific validation method.
34
//
35
// If the validator cannot determine the value or it is not supported, then NotValidatableError will be returned
36
// when calling the validator.Validate method.
37
func Value(value interface{}, options ...Option) Argument {
38 1
	return argumentFunc(func(arguments *Arguments) error {
39 1
		v, err := newValueValidator(value, options)
40 1
		if err != nil {
41 1
			return err
42
		}
43
44 1
		arguments.addValidator(v)
45
46 1
		return nil
47
	})
48
}
49
50
// PropertyValue argument is an alias for Value that automatically adds property name to the current scope.
51
func PropertyValue(name string, value interface{}, options ...Option) Argument {
52 1
	return Value(value, append([]Option{PropertyName(name)}, options...)...)
53
}
54
55
// Bool argument is used to validate boolean values.
56
func Bool(value bool, options ...Option) Argument {
57 1
	return argumentFunc(func(arguments *Arguments) error {
58 1
		arguments.addValidator(newBoolValidator(&value, options))
59
60 1
		return nil
61
	})
62
}
63
64
// BoolProperty argument is an alias for Bool that automatically adds property name to the current scope.
65
func BoolProperty(name string, value bool, options ...Option) Argument {
66 1
	return Bool(value, append([]Option{PropertyName(name)}, options...)...)
67
}
68
69
// NilBool argument is used to validate nillable boolean values.
70
func NilBool(value *bool, options ...Option) Argument {
71 1
	return argumentFunc(func(arguments *Arguments) error {
72 1
		arguments.addValidator(newBoolValidator(value, options))
73
74 1
		return nil
75
	})
76
}
77
78
// NilBoolProperty argument is an alias for NilBool that automatically adds property name to the current scope.
79
func NilBoolProperty(name string, value *bool, options ...Option) Argument {
80 1
	return NilBool(value, append([]Option{PropertyName(name)}, options...)...)
81
}
82
83
// Number argument is used to validate numbers (any types of integers or floats). At the moment it uses
84
// reflection to detect numeric value. Given value is internally converted into int64 or float64 to make comparisons.
85
//
86
// Warning! This method will be changed after generics implementation in Go.
87
func Number(value interface{}, options ...Option) Argument {
88 1
	return argumentFunc(func(arguments *Arguments) error {
89 1
		number, err := generic.NewNumber(value)
90 1
		if err != nil {
91 1
			return fmt.Errorf(`cannot convert value "%v" to number: %w`, value, err)
92
		}
93
94 1
		arguments.addValidator(newNumberValidator(*number, options))
95
96 1
		return nil
97
	})
98
}
99
100
// NumberProperty argument is an alias for Number that automatically adds property name to the current scope.
101
func NumberProperty(name string, value interface{}, options ...Option) Argument {
102 1
	return Number(value, append([]Option{PropertyName(name)}, options...)...)
103
}
104
105
// String argument is used to validate strings.
106
func String(value string, options ...Option) Argument {
107 1
	return argumentFunc(func(arguments *Arguments) error {
108 1
		arguments.addValidator(newStringValidator(&value, options))
109
110 1
		return nil
111
	})
112
}
113
114
// StringProperty argument is an alias for String that automatically adds property name to the current scope.
115
func StringProperty(name string, value string, options ...Option) Argument {
116 1
	return String(value, append([]Option{PropertyName(name)}, options...)...)
117
}
118
119
// NilString argument is used to validate nillable strings.
120
func NilString(value *string, options ...Option) Argument {
121 1
	return argumentFunc(func(arguments *Arguments) error {
122 1
		arguments.addValidator(newStringValidator(value, options))
123
124 1
		return nil
125
	})
126
}
127
128
// NilStringProperty argument is an alias for NilString that automatically adds property name to the current scope.
129
func NilStringProperty(name string, value *string, options ...Option) Argument {
130 1
	return NilString(value, append([]Option{PropertyName(name)}, options...)...)
131
}
132
133
// Strings argument is used to validate slice of strings.
134
func Strings(values []string, options ...Option) Argument {
135 1
	return argumentFunc(func(arguments *Arguments) error {
136 1
		arguments.addValidator(newStringsValidator(values, options))
137
138 1
		return nil
139
	})
140
}
141
142
// StringsProperty argument is an alias for Strings that automatically adds property name to the current scope.
143
func StringsProperty(name string, values []string, options ...Option) Argument {
144 1
	return Strings(values, append([]Option{PropertyName(name)}, options...)...)
145
}
146
147
// Iterable argument is used to validate arrays, slices, or maps. At the moment it uses reflection
148
// to iterate over values. So you can expect a performance hit using this method. For better performance
149
// it is recommended to make a custom type that implements the Validatable interface.
150
//
151
// Warning! This argument is subject to change in the final versions of the library.
152
func Iterable(value interface{}, options ...Option) Argument {
153 1
	return argumentFunc(func(arguments *Arguments) error {
154 1
		iterable, err := generic.NewIterable(value)
155 1
		if err != nil {
156 1
			return fmt.Errorf(`cannot convert value "%v" to iterable: %w`, value, err)
157
		}
158
159 1
		arguments.addValidator(newIterableValidator(iterable, options))
160
161 1
		return nil
162
	})
163
}
164
165
// IterableProperty argument is an alias for Iterable that automatically adds property name to the current scope.
166
func IterableProperty(name string, value interface{}, options ...Option) Argument {
167 1
	return Iterable(value, append([]Option{PropertyName(name)}, options...)...)
168
}
169
170
// Countable argument can be used to validate size of an array, slice, or map. You can pass result of len()
171
// function as an argument.
172
func Countable(count int, options ...Option) Argument {
173 1
	return argumentFunc(func(arguments *Arguments) error {
174 1
		arguments.addValidator(newCountableValidator(count, options))
175
176 1
		return nil
177
	})
178
}
179
180
// CountableProperty argument is an alias for Countable that automatically adds property name to the current scope.
181
func CountableProperty(name string, count int, options ...Option) Argument {
182 1
	return Countable(count, append([]Option{PropertyName(name)}, options...)...)
183
}
184
185
// Time argument is used to validate time.Time value.
186
func Time(value time.Time, options ...Option) Argument {
187 1
	return argumentFunc(func(arguments *Arguments) error {
188 1
		arguments.addValidator(newTimeValidator(&value, options))
189
190 1
		return nil
191
	})
192
}
193
194
// TimeProperty argument is an alias for Time that automatically adds property name to the current scope.
195
func TimeProperty(name string, value time.Time, options ...Option) Argument {
196 1
	return Time(value, append([]Option{PropertyName(name)}, options...)...)
197
}
198
199
// NilTime argument is used to validate nillable time.Time value.
200
func NilTime(value *time.Time, options ...Option) Argument {
201 1
	return argumentFunc(func(arguments *Arguments) error {
202 1
		arguments.addValidator(newTimeValidator(value, options))
203
204 1
		return nil
205
	})
206
}
207
208
// NilTimeProperty argument is an alias for NilTime that automatically adds property name to the current scope.
209
func NilTimeProperty(name string, value *time.Time, options ...Option) Argument {
210 1
	return NilTime(value, append([]Option{PropertyName(name)}, options...)...)
211
}
212
213
// Each is used to validate each value of iterable (array, slice, or map). At the moment it uses reflection
214
// to iterate over values. So you can expect a performance hit using this method. For better performance
215
// it is recommended to make a custom type that implements the Validatable interface. Also, you can use
216
// EachString argument to validate slice of strings.
217
//
218
// Warning! This argument is subject to change in the final versions of the library.
219
func Each(value interface{}, options ...Option) Argument {
220 1
	return argumentFunc(func(arguments *Arguments) error {
221 1
		iterable, err := generic.NewIterable(value)
222 1
		if err != nil {
223 1
			return fmt.Errorf(`cannot convert value "%v" to iterable: %w`, value, err)
224
		}
225
226 1
		arguments.addValidator(newEachValidator(iterable, options))
227
228 1
		return nil
229
	})
230
}
231
232
// EachProperty argument is an alias for Each that automatically adds property name to the current scope.
233
func EachProperty(name string, value interface{}, options ...Option) Argument {
234 1
	return Each(value, append([]Option{PropertyName(name)}, options...)...)
235
}
236
237
// EachString is used to validate a slice of strings. This is a more performant version of Each argument.
238
func EachString(values []string, options ...Option) Argument {
239 1
	return argumentFunc(func(arguments *Arguments) error {
240 1
		arguments.addValidator(newEachStringValidator(values, options))
241
242 1
		return nil
243
	})
244
}
245
246
// EachStringProperty argument is an alias for EachString that automatically adds property name to the current scope.
247
func EachStringProperty(name string, values []string, options ...Option) Argument {
248 1
	return EachString(values, append([]Option{PropertyName(name)}, options...)...)
249
}
250
251
// Valid is used to run validation on the Validatable type. This method is recommended
252
// to run a complex validation process.
253
func Valid(value Validatable, options ...Option) Argument {
254 1
	return argumentFunc(func(arguments *Arguments) error {
255 1
		arguments.addValidator(newValidValidator(value, options))
256
257 1
		return nil
258
	})
259
}
260
261
// ValidProperty argument is an alias for Valid that automatically adds property name to the current scope.
262
func ValidProperty(name string, value Validatable, options ...Option) Argument {
263 1
	return Valid(value, append([]Option{PropertyName(name)}, options...)...)
264
}
265
266
// Language argument sets the current language for translation of a violation message.
267
//
268
// Example
269
//  err := validator.Validate(
270
//      Language(language.Russian),
271
//      String(&s, it.IsNotBlank()), // all violations created in scope will be translated into Russian
272
//  )
273
func Language(tag language.Tag) Argument {
274 1
	return argumentFunc(func(arguments *Arguments) error {
275 1
		arguments.scope.language = tag
276
277 1
		return nil
278
	})
279
}
280
281
// NewArgument can be used to implement your own validation arguments for the specific types.
282
// See example for more details.
283
func NewArgument(options []Option, validate ValidateByConstraintFunc) Argument {
284 1
	return argumentFunc(func(arguments *Arguments) error {
285 1
		arguments.addValidator(newValidator(options, validate))
286
287 1
		return nil
288
	})
289
}
290