Skip to content

Commit

Permalink
Support slice and array of BindUnmarshaler
Browse files Browse the repository at this point in the history
Allows form binding of []BindUnmarshaler and [x]BindUnmarshaler
  • Loading branch information
jmfederico committed Jun 8, 2024
1 parent 64ead9e commit 64f4975
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
25 changes: 25 additions & 0 deletions binding/form_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,26 @@ func trySetCustom(val string, value reflect.Value) (isSet bool, err error) {
return false, nil
}

// trySetArrayOfCustom works as trySetCustom but for an array of custom values
// If the value implements the BindUnmarshaler interface, it will be used to set the values,
// we will return `true` to skip the default value setting.
func trySetArrayOfCustom(vals []string, arrayValue reflect.Value) (isSet bool, err error) {
switch arrayValue.Index(0).Addr().Interface().(type) {
case BindUnmarshaler:
for i, s := range vals {
{
err := arrayValue.Index(i).Addr().Interface().(BindUnmarshaler).UnmarshalParam(s)
if err != nil {
return true, err

Check warning on line 195 in binding/form_mapping.go

View check run for this annotation

Codecov / codecov/patch

binding/form_mapping.go#L195

Added line #L195 was not covered by tests
}
}
}
return true, nil
default:
return false, nil
}
}

func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSet bool, err error) {
vs, ok := form[tagValue]
if !ok && !opt.isDefaultExists {
Expand Down Expand Up @@ -379,6 +399,11 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
}

func setArray(vals []string, value reflect.Value, field reflect.StructField) error {
ok, err := trySetArrayOfCustom(vals, value)
if ok {
return err
}

for i, s := range vals {
err := setWithProperType(s, value.Index(i), field)
if err != nil {
Expand Down
20 changes: 20 additions & 0 deletions binding/form_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,23 @@ func TestMappingCustomArrayForm(t *testing.T) {
expected, _ := convertTo(val)
assert.EqualValues(t, expected, s.FileData)
}

func TestMappingSliceWithCustomUnmarshal(t *testing.T) {
var s struct {
HexSlice []customUnmarshalParamHex `form:"hex_slice"`
}
err := mappingByPtr(&s, formSource{"hex_slice": {`f5`, `f6`}}, "form")
assert.NoError(t, err)

assert.EqualValues(t, []customUnmarshalParamHex{245, 246}, s.HexSlice)
}

func TestMappingArrayWithCustomUnmarshal(t *testing.T) {
var s struct {
HexArray [2]customUnmarshalParamHex `form:"hex_array"`
}
err := mappingByPtr(&s, formSource{"hex_array": {`f5`, `f6`}}, "form")
assert.NoError(t, err)

assert.EqualValues(t, [2]customUnmarshalParamHex{245, 246}, s.HexArray)
}

0 comments on commit 64f4975

Please sign in to comment.