Support slice and array of BindUnmarshaler

Allows form binding of []BindUnmarshaler and [x]BindUnmarshaler
This commit is contained in:
Federico Jaramillo Martinez 2024-06-08 13:06:29 +02:00
parent 64ead9e6bd
commit 64f4975cd3
2 changed files with 45 additions and 0 deletions

View File

@ -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
}
}
}
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 {
@ -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 {

View File

@ -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)
}