Test Failed
Push — main ( e725b3...a33214 )
by Igor
01:56
created

flow_control.go   A

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 40
eloc 120
dl 0
loc 239
rs 9.2
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A validation.WhenArgument.With 0 3 1
A validation.WhenArgument.setUp 0 10 3
A validation.WhenArgument.Then 0 3 1
A validation.When 0 2 1
A validation.WhenArgument.Else 0 3 1
A validation.WhenGroupsArgument.With 0 3 1
A validation.WhenGroupsArgument.Else 0 3 1
A validation.AtLeastOneOfArgument.When 0 3 1
B validation.SequentialArgument.setUp 0 19 6
A validation.SequentialArgument.With 0 3 1
A validation.WhenGroupsArgument.setUp 0 10 3
A validation.Sequentially 0 2 1
A validation.WhenGroups 0 2 1
A validation.SequentialArgument.When 0 3 1
A validation.WhenGroupsArgument.Then 0 3 1
A validation.AtLeastOneOf 0 2 1
B validation.AtLeastOneOfArgument.setUp 0 21 6
A validation.AtLeastOneOfArgument.With 0 3 1
A validation.AllArgument.When 0 3 1
A validation.AllArgument.setUp 0 16 5
A validation.AllArgument.With 0 3 1
A validation.All 0 2 1
1
package validation
2
3
// WhenArgument is used to build conditional validation. Use the When function to initiate a conditional check.
4
// If the condition is true, then the arguments passed through the Then function will be processed.
5
// Otherwise, the arguments passed through the Else function will be processed.
6
type WhenArgument struct {
7
	isTrue        bool
8
	options       []Option
9
	thenArguments []Argument
10
	elseArguments []Argument
11
}
12
13
// When function is used to initiate conditional validation.
14
// If the condition is true, then the arguments passed through the Then function will be processed.
15
// Otherwise, the arguments passed through the Else function will be processed.
16
func When(isTrue bool) WhenArgument {
17
	return WhenArgument{isTrue: isTrue}
18
}
19
20
// Then function is used to set a sequence of arguments to be processed if the condition is true.
21
func (arg WhenArgument) Then(arguments ...Argument) WhenArgument {
22
	arg.thenArguments = arguments
23
	return arg
24
}
25
26
// Else function is used to set a sequence of arguments to be processed if a condition is false.
27
func (arg WhenArgument) Else(arguments ...Argument) WhenArgument {
28
	arg.elseArguments = arguments
29
	return arg
30
}
31
32
// With returns a copy of WhenArgument with appended options.
33
func (arg WhenArgument) With(options ...Option) WhenArgument {
34
	arg.options = append(arg.options, options...)
35
	return arg
36
}
37
38
func (arg WhenArgument) setUp(ctx *executionContext) {
39
	ctx.addValidator(arg.options, func(scope Scope) (*ViolationList, error) {
40
		var err error
41
		if arg.isTrue {
42
			err = scope.Validate(arg.thenArguments...)
43
		} else {
44
			err = scope.Validate(arg.elseArguments...)
45
		}
46
47
		return unwrapViolationList(err)
48
	})
49
}
50
51
// WhenGroupsArgument is used to build conditional validation based on groups. Use the WhenGroups function
52
// to initiate a conditional check. If validation group matches to the validator one,
53
// then the arguments passed through the Then function will be processed.
54
// Otherwise, the arguments passed through the Else function will be processed.
55
type WhenGroupsArgument struct {
56
	groups        []string
57
	options       []Option
58
	thenArguments []Argument
59
	elseArguments []Argument
60
}
61
62
// WhenGroups is used to build conditional validation based on groups. If validation group matches to
63
// the validator one, then the arguments passed through the Then function will be processed.
64
// Otherwise, the arguments passed through the Else function will be processed.
65
func WhenGroups(groups ...string) WhenGroupsArgument {
66
	return WhenGroupsArgument{groups: groups}
67
}
68
69
// Then function is used to set a sequence of arguments to be processed if the validation group is active.
70
func (arg WhenGroupsArgument) Then(arguments ...Argument) WhenGroupsArgument {
71
	arg.thenArguments = arguments
72
	return arg
73
}
74
75
// Else function is used to set a sequence of arguments to be processed if the validation group is active.
76
func (arg WhenGroupsArgument) Else(arguments ...Argument) WhenGroupsArgument {
77
	arg.elseArguments = arguments
78
	return arg
79
}
80
81
// With returns a copy of WhenArgument with appended options.
82
func (arg WhenGroupsArgument) With(options ...Option) WhenGroupsArgument {
83
	arg.options = append(arg.options, options...)
84
	return arg
85
}
86
87
func (arg WhenGroupsArgument) setUp(ctx *executionContext) {
88
	ctx.addValidator(arg.options, func(scope Scope) (*ViolationList, error) {
89
		var err error
90
		if scope.IsIgnored(arg.groups...) {
91
			err = scope.Validate(arg.elseArguments...)
92
		} else {
93
			err = scope.Validate(arg.thenArguments...)
94
		}
95
96
		return unwrapViolationList(err)
97
	})
98
}
99
100
// SequentialArgument can be used to interrupt validation process when the first violation is raised.
101
type SequentialArgument struct {
102
	isIgnored bool
103
	options   []Option
104
	arguments []Argument
105
}
106
107
// Sequentially function used to run validation process step-by-step.
108
func Sequentially(arguments ...Argument) SequentialArgument {
109
	return SequentialArgument{arguments: arguments}
110
}
111
112
// With returns a copy of SequentialArgument with appended options.
113
func (arg SequentialArgument) With(options ...Option) SequentialArgument {
114
	arg.options = append(arg.options, options...)
115
	return arg
116
}
117
118
// When enables conditional validation of this argument. If the expression evaluates to false,
119
// then the argument will be ignored.
120
func (arg SequentialArgument) When(condition bool) SequentialArgument {
121
	arg.isIgnored = !condition
122
	return arg
123
}
124
125
func (arg SequentialArgument) setUp(ctx *executionContext) {
126
	ctx.addValidator(arg.options, func(scope Scope) (*ViolationList, error) {
127
		if arg.isIgnored {
128
			return nil, nil
129
		}
130
131
		violations := &ViolationList{}
132
133
		for _, argument := range arg.arguments {
134
			err := violations.AppendFromError(scope.Validate(argument))
135
			if err != nil {
136
				return nil, err
137
			}
138
			if violations.len > 0 {
139
				return violations, nil
140
			}
141
		}
142
143
		return violations, nil
144
	})
145
}
146
147
// AtLeastOneOfArgument can be used to set up validation process to check that the value satisfies
148
// at least one of the given constraints. The validation stops as soon as one constraint is satisfied.
149
type AtLeastOneOfArgument struct {
150
	isIgnored bool
151
	options   []Option
152
	arguments []Argument
153
}
154
155
// AtLeastOneOf can be used to set up validation process to check that the value satisfies
156
// at least one of the given constraints. The validation stops as soon as one constraint is satisfied.
157
func AtLeastOneOf(arguments ...Argument) AtLeastOneOfArgument {
158
	return AtLeastOneOfArgument{arguments: arguments}
159
}
160
161
// With returns a copy of AtLeastOneOfArgument with appended options.
162
func (arg AtLeastOneOfArgument) With(options ...Option) AtLeastOneOfArgument {
163
	arg.options = append(arg.options, options...)
164
	return arg
165
}
166
167
// When enables conditional validation of this argument. If the expression evaluates to false,
168
// then the argument will be ignored.
169
func (arg AtLeastOneOfArgument) When(condition bool) AtLeastOneOfArgument {
170
	arg.isIgnored = !condition
171
	return arg
172
}
173
174
func (arg AtLeastOneOfArgument) setUp(ctx *executionContext) {
175
	ctx.addValidator(arg.options, func(scope Scope) (*ViolationList, error) {
176
		if arg.isIgnored {
177
			return nil, nil
178
		}
179
180
		violations := &ViolationList{}
181
182
		for _, argument := range arg.arguments {
183
			violation := scope.Validate(argument)
184
			if violation == nil {
185
				return nil, nil
186
			}
187
188
			err := violations.AppendFromError(violation)
189
			if err != nil {
190
				return nil, err
191
			}
192
		}
193
194
		return violations, nil
195
	})
196
}
197
198
// AllArgument can be used to interrupt validation process when the first violation is raised.
199
type AllArgument struct {
200
	isIgnored bool
201
	options   []Option
202
	arguments []Argument
203
}
204
205
// All runs validation for each argument. It works exactly as validator.Validate method.
206
// It can be helpful to build complex validation process.
207
func All(arguments ...Argument) AllArgument {
208
	return AllArgument{arguments: arguments}
209
}
210
211
// With returns a copy of AllArgument with appended options.
212
func (arg AllArgument) With(options ...Option) AllArgument {
213
	arg.options = append(arg.options, options...)
214
	return arg
215
}
216
217
// When enables conditional validation of this argument. If the expression evaluates to false,
218
// then the argument will be ignored.
219
func (arg AllArgument) When(condition bool) AllArgument {
220
	arg.isIgnored = !condition
221
	return arg
222
}
223
224
func (arg AllArgument) setUp(ctx *executionContext) {
225
	ctx.addValidator(arg.options, func(scope Scope) (*ViolationList, error) {
226
		if arg.isIgnored {
227
			return nil, nil
228
		}
229
230
		violations := &ViolationList{}
231
232
		for _, argument := range arg.arguments {
233
			err := violations.AppendFromError(scope.Validate(argument))
234
			if err != nil {
235
				return nil, err
236
			}
237
		}
238
239
		return violations, nil
240
	})
241
}
242