From 64f4975cd3f88ef9424446de1952ecae9e1fce54 Mon Sep 17 00:00:00 2001 From: Federico Jaramillo Martinez Date: Sat, 8 Jun 2024 13:06:29 +0200 Subject: [PATCH 1/3] Support slice and array of BindUnmarshaler Allows form binding of []BindUnmarshaler and [x]BindUnmarshaler --- binding/form_mapping.go | 25 +++++++++++++++++++++++++ binding/form_mapping_test.go | 20 ++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 33389b2889..fc1f3f393b 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -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 { diff --git a/binding/form_mapping_test.go b/binding/form_mapping_test.go index afd51f9d88..16b01ec4ee 100644 --- a/binding/form_mapping_test.go +++ b/binding/form_mapping_test.go @@ -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) +} From 9c6df94f7cb7d5b6010d94b47c85cc45eedbae86 Mon Sep 17 00:00:00 2001 From: Federico Jaramillo Martinez Date: Thu, 13 Jun 2024 10:41:31 +0200 Subject: [PATCH 2/3] Test for error on Unmarshal --- binding/form_mapping_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/binding/form_mapping_test.go b/binding/form_mapping_test.go index 16b01ec4ee..3eb5482e4b 100644 --- a/binding/form_mapping_test.go +++ b/binding/form_mapping_test.go @@ -529,3 +529,14 @@ func TestMappingArrayWithCustomUnmarshal(t *testing.T) { assert.EqualValues(t, [2]customUnmarshalParamHex{245, 246}, s.HexArray) } + +func TestMappingArrayWithUnkownType(t *testing.T) { + var s struct { + U []customUnmarshalParamHex + } + err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form") + assert.Error(t, err) + + var expectedError *strconv.NumError + assert.ErrorAs(t, err, &expectedError) +} From de9a9eb0bc9af66576ef2e0aaf9e3a8640f18820 Mon Sep 17 00:00:00 2001 From: Federico Jaramillo Martinez Date: Thu, 27 Jun 2024 21:34:13 +0200 Subject: [PATCH 3/3] Fix spelling --- binding/form_mapping_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binding/form_mapping_test.go b/binding/form_mapping_test.go index 3eb5482e4b..00d0f9fa3c 100644 --- a/binding/form_mapping_test.go +++ b/binding/form_mapping_test.go @@ -530,7 +530,7 @@ func TestMappingArrayWithCustomUnmarshal(t *testing.T) { assert.EqualValues(t, [2]customUnmarshalParamHex{245, 246}, s.HexArray) } -func TestMappingArrayWithUnkownType(t *testing.T) { +func TestMappingArrayWithUnknownType(t *testing.T) { var s struct { U []customUnmarshalParamHex }