Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ func (b *ValueBinder) intsValue(sourceParam string, dest any, valueMustExist boo
}

func (b *ValueBinder) ints(sourceParam string, values []string, dest any) *ValueBinder {
errorsBefore := len(b.errors)
switch d := dest.(type) {
case *[]int64:
tmp := make([]int64, len(values))
Expand All @@ -584,7 +585,7 @@ func (b *ValueBinder) ints(sourceParam string, values []string, dest any) *Value
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]int32:
Expand All @@ -595,7 +596,7 @@ func (b *ValueBinder) ints(sourceParam string, values []string, dest any) *Value
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]int16:
Expand All @@ -606,7 +607,7 @@ func (b *ValueBinder) ints(sourceParam string, values []string, dest any) *Value
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]int8:
Expand All @@ -617,7 +618,7 @@ func (b *ValueBinder) ints(sourceParam string, values []string, dest any) *Value
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]int:
Expand All @@ -628,7 +629,7 @@ func (b *ValueBinder) ints(sourceParam string, values []string, dest any) *Value
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
}
Expand Down Expand Up @@ -803,6 +804,7 @@ func (b *ValueBinder) uintsValue(sourceParam string, dest any, valueMustExist bo
}

func (b *ValueBinder) uints(sourceParam string, values []string, dest any) *ValueBinder {
errorsBefore := len(b.errors)
switch d := dest.(type) {
case *[]uint64:
tmp := make([]uint64, len(values))
Expand All @@ -812,7 +814,7 @@ func (b *ValueBinder) uints(sourceParam string, values []string, dest any) *Valu
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]uint32:
Expand All @@ -823,7 +825,7 @@ func (b *ValueBinder) uints(sourceParam string, values []string, dest any) *Valu
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]uint16:
Expand All @@ -834,7 +836,7 @@ func (b *ValueBinder) uints(sourceParam string, values []string, dest any) *Valu
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]uint8: // byte is alias to uint8
Expand All @@ -845,7 +847,7 @@ func (b *ValueBinder) uints(sourceParam string, values []string, dest any) *Valu
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]uint:
Expand All @@ -856,7 +858,7 @@ func (b *ValueBinder) uints(sourceParam string, values []string, dest any) *Valu
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
}
Expand Down Expand Up @@ -965,14 +967,15 @@ func (b *ValueBinder) boolsValue(sourceParam string, dest *[]bool, valueMustExis
}

func (b *ValueBinder) bools(sourceParam string, values []string, dest *[]bool) *ValueBinder {
errorsBefore := len(b.errors)
tmp := make([]bool, len(values))
for i, v := range values {
b.bool(sourceParam, v, &tmp[i])
if b.failFast && b.errors != nil {
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*dest = tmp
}
return b
Expand Down Expand Up @@ -1056,6 +1059,7 @@ func (b *ValueBinder) floatsValue(sourceParam string, dest any, valueMustExist b
}

func (b *ValueBinder) floats(sourceParam string, values []string, dest any) *ValueBinder {
errorsBefore := len(b.errors)
switch d := dest.(type) {
case *[]float64:
tmp := make([]float64, len(values))
Expand All @@ -1065,7 +1069,7 @@ func (b *ValueBinder) floats(sourceParam string, values []string, dest any) *Val
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
case *[]float32:
Expand All @@ -1076,7 +1080,7 @@ func (b *ValueBinder) floats(sourceParam string, values []string, dest any) *Val
return b
}
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*d = tmp
}
}
Expand Down Expand Up @@ -1157,6 +1161,7 @@ func (b *ValueBinder) times(sourceParam string, dest *[]time.Time, layout string
return b
}

errorsBefore := len(b.errors)
tmp := make([]time.Time, len(values))
for i, v := range values {
t, err := time.Parse(layout, v)
Expand All @@ -1169,7 +1174,7 @@ func (b *ValueBinder) times(sourceParam string, dest *[]time.Time, layout string
}
tmp[i] = t
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*dest = tmp
}
return b
Expand Down Expand Up @@ -1232,6 +1237,7 @@ func (b *ValueBinder) durationsValue(sourceParam string, dest *[]time.Duration,
}

func (b *ValueBinder) durations(sourceParam string, values []string, dest *[]time.Duration) *ValueBinder {
errorsBefore := len(b.errors)
tmp := make([]time.Duration, len(values))
for i, v := range values {
t, err := time.ParseDuration(v)
Expand All @@ -1244,7 +1250,7 @@ func (b *ValueBinder) durations(sourceParam string, values []string, dest *[]tim
}
tmp[i] = t
}
if b.errors == nil {
if len(b.errors) == errorsBefore {
*dest = tmp
}
return b
Expand Down
32 changes: 32 additions & 0 deletions binder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,38 @@ func TestValueBinder_Int_errorMessage(t *testing.T) {
assert.EqualError(t, errs[1], `code=400, message=failed to bind field value to uint, err=strconv.ParseUint: parsing "nope": invalid syntax, field=param`)
}

func TestValueBinder_FailFastFalseBindsValidSlicesAfterError(t *testing.T) {
c := createTestContext("/?bad=nope&ints=1&ints=2&uints=3&uints=4&bools=true&bools=false&floats=1.5&floats=2.5&times=2024-01-02&times=2024-01-03&durations=1s&durations=2s", nil, nil)

var bad int
ints := []int{99}
uints := []uint{99}
bools := []bool{false}
floats := []float64{99}
times := []time.Time{{}}
durations := []time.Duration{99}
errs := QueryParamsBinder(c).FailFast(false).
Int("bad", &bad).
Ints("ints", &ints).
Uints("uints", &uints).
Bools("bools", &bools).
Float64s("floats", &floats).
Times("times", &times, time.DateOnly).
Durations("durations", &durations).
BindErrors()

assert.Len(t, errs, 1)
assert.Equal(t, []int{1, 2}, ints)
assert.Equal(t, []uint{3, 4}, uints)
assert.Equal(t, []bool{true, false}, bools)
assert.Equal(t, []float64{1.5, 2.5}, floats)
assert.Equal(t, []time.Time{
time.Date(2024, time.January, 2, 0, 0, 0, 0, time.UTC),
time.Date(2024, time.January, 3, 0, 0, 0, 0, time.UTC),
}, times)
assert.Equal(t, []time.Duration{time.Second, 2 * time.Second}, durations)
}

func TestValueBinder_Uint64_uintValue(t *testing.T) {
var testCases = []struct {
name string
Expand Down