Skip to content

Commit 8c315f2

Browse files
committed
feat: new option for multiple error returned
1 parent 53c4d6b commit 8c315f2

File tree

4 files changed

+120
-4
lines changed

4 files changed

+120
-4
lines changed

options.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,13 @@ func WithPrivateFieldValidation() Option {
2424
v.privateFieldValidation = true
2525
}
2626
}
27+
28+
// WithMultipleErrorsReturned enables multi error return from a single struct field.
29+
//
30+
// By opting into this feature you are acknowledging that you are aware of the risks and accept any current or future
31+
// consequences of using this feature.
32+
func WithMultipleErrorsReturned() Option {
33+
return func(v *Validate) {
34+
v.multipleErrorsReturned = true
35+
}
36+
}

validator.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
135135
kind: kind,
136136
},
137137
)
138-
return
138+
if !v.v.multipleErrorsReturned {
139+
return
140+
}
139141
}
140142

141143
v.str1 = string(append(ns, cf.altName...))
@@ -160,7 +162,9 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
160162
typ: current.Type(),
161163
},
162164
)
163-
return
165+
if !v.v.multipleErrorsReturned {
166+
return
167+
}
164168
}
165169
}
166170

@@ -453,7 +457,9 @@ OUTER:
453457
)
454458
}
455459

456-
return
460+
if !v.v.multipleErrorsReturned {
461+
return
462+
}
457463
}
458464

459465
ct = ct.next
@@ -492,7 +498,9 @@ OUTER:
492498
},
493499
)
494500

495-
return
501+
if !v.v.multipleErrorsReturned {
502+
return
503+
}
496504
}
497505
ct = ct.next
498506
}

validator_instance.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ type Validate struct {
9696
hasTagNameFunc bool
9797
requiredStructEnabled bool
9898
privateFieldValidation bool
99+
multipleErrorsReturned bool
99100
}
100101

101102
// New returns a new instance of 'validate' with sane defaults.

validator_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14975,3 +14975,100 @@ func TestRequiredIfWithArrays(t *testing.T) {
1497514975
Equal(t, err, nil) // No error - Text has value
1497614976
})
1497714977
}
14978+
14979+
func TestMultipleErrorsOption(t *testing.T) {
14980+
type tc struct {
14981+
stct interface{}
14982+
errorNum int
14983+
}
14984+
14985+
tcs := []tc{
14986+
{
14987+
stct: &struct {
14988+
F1 int8 `validate:"eq=10,gte=10"`
14989+
F2 int16 `validate:"eq=10,gte=10"`
14990+
F3 int32 `validate:"eq=10,gte=10"`
14991+
F4 int64 `validate:"eq=10,gte=10"`
14992+
}{},
14993+
errorNum: 8,
14994+
},
14995+
{
14996+
stct: &struct {
14997+
F1 uint8 `validate:"eq=10,gte=10"`
14998+
F2 uint16 `validate:"eq=10,gte=10"`
14999+
F3 uint32 `validate:"eq=10,gte=10"`
15000+
F4 uint64 `validate:"eq=10,gte=10"`
15001+
}{
15002+
F1: 100,
15003+
},
15004+
errorNum: 7,
15005+
},
15006+
{
15007+
stct: &struct {
15008+
F1 string `validate:"eq=10,gte=10"`
15009+
F2 string `validate:"eq=10,gte=10"`
15010+
}{},
15011+
errorNum: 4,
15012+
},
15013+
{
15014+
stct: &struct {
15015+
F1 float32 `validate:"eq=10,gte=10"`
15016+
F2 float64 `validate:"eq=10,gte=10"`
15017+
}{},
15018+
errorNum: 4,
15019+
},
15020+
{
15021+
stct: struct {
15022+
F1 int8 `validate:"eq=10,gte=10"`
15023+
F2 int16 `validate:"eq=10,gte=10"`
15024+
F3 int32 `validate:"eq=10,gte=10"`
15025+
F4 int64 `validate:"eq=10,gte=10"`
15026+
}{},
15027+
errorNum: 8,
15028+
},
15029+
{
15030+
stct: struct {
15031+
F1 uint8 `validate:"eq=10,gte=10"`
15032+
F2 uint16 `validate:"eq=10,gte=10"`
15033+
F3 uint32 `validate:"eq=10,gte=10"`
15034+
F4 uint64 `validate:"eq=10,gte=10"`
15035+
}{},
15036+
errorNum: 8,
15037+
},
15038+
{
15039+
stct: struct {
15040+
F1 float32 `validate:"eq=10,gte=10"`
15041+
F2 float64 `validate:"eq=10,gte=10"`
15042+
}{},
15043+
errorNum: 4,
15044+
},
15045+
{
15046+
stct: struct {
15047+
F1 int `validate:"eq=10,gte=10"`
15048+
F2 struct {
15049+
F3 int `validate:"eq=10,gte=10"`
15050+
}
15051+
}{},
15052+
errorNum: 4,
15053+
},
15054+
{
15055+
stct: &struct {
15056+
F1 int `validate:"eq=10,gte=10"`
15057+
F2 struct {
15058+
F3 int `validate:"eq=10,gte=10"`
15059+
}
15060+
}{},
15061+
errorNum: 4,
15062+
},
15063+
}
15064+
15065+
validate := New(WithMultipleErrorsReturned())
15066+
15067+
for _, tc := range tcs {
15068+
err := validate.Struct(tc.stct)
15069+
NotEqual(t, err, nil)
15070+
15071+
errs := err.(ValidationErrors)
15072+
Equal(t, len(errs), tc.errorNum)
15073+
}
15074+
}

0 commit comments

Comments
 (0)