mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-14 20:22:20 +08:00
feat(binding): add support for slices with BindUnmarshaler elements (#4312)
Fixes issue where slice/array elements implementing BindUnmarshaler interface were not properly handled. The setArray function now checks if elements implement custom unmarshaling before falling back to default type conversion. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
dab5944a7b
commit
906c864012
@ -449,9 +449,16 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
|
|||||||
|
|
||||||
func setArray(vals []string, value reflect.Value, field reflect.StructField) error {
|
func setArray(vals []string, value reflect.Value, field reflect.StructField) error {
|
||||||
for i, s := range vals {
|
for i, s := range vals {
|
||||||
err := setWithProperType(s, value.Index(i), field)
|
elementValue := value.Index(i)
|
||||||
if err != nil {
|
if isSet, err := trySetCustom(s, elementValue); isSet {
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := setWithProperType(s, elementValue, field)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -635,3 +635,65 @@ func TestMappingCustomArrayForm(t *testing.T) {
|
|||||||
expected, _ := convertTo(val)
|
expected, _ := convertTo(val)
|
||||||
assert.Equal(t, expected, s.FileData)
|
assert.Equal(t, expected, s.FileData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMappingSliceOfCustomBindUnmarshalerElementsUri(t *testing.T) {
|
||||||
|
var s struct {
|
||||||
|
Items []customUnmarshalParamType `uri:"items"`
|
||||||
|
}
|
||||||
|
err := mappingByPtr(&s, formSource{"items": {"http:path1:name1", "https:path2:name2"}}, "uri")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, s.Items, 2)
|
||||||
|
assert.Equal(t, "http", s.Items[0].Protocol)
|
||||||
|
assert.Equal(t, "path1", s.Items[0].Path)
|
||||||
|
assert.Equal(t, "name1", s.Items[0].Name)
|
||||||
|
assert.Equal(t, "https", s.Items[1].Protocol)
|
||||||
|
assert.Equal(t, "path2", s.Items[1].Path)
|
||||||
|
assert.Equal(t, "name2", s.Items[1].Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMappingSliceOfCustomBindUnmarshalerElementsForm(t *testing.T) {
|
||||||
|
var s struct {
|
||||||
|
Items []customUnmarshalParamType `form:"items"`
|
||||||
|
}
|
||||||
|
err := mappingByPtr(&s, formSource{"items": {"tcp:socket1:server", "udp:socket2:client"}}, "form")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, s.Items, 2)
|
||||||
|
assert.Equal(t, "tcp", s.Items[0].Protocol)
|
||||||
|
assert.Equal(t, "socket1", s.Items[0].Path)
|
||||||
|
assert.Equal(t, "server", s.Items[0].Name)
|
||||||
|
assert.Equal(t, "udp", s.Items[1].Protocol)
|
||||||
|
assert.Equal(t, "socket2", s.Items[1].Path)
|
||||||
|
assert.Equal(t, "client", s.Items[1].Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMappingArrayOfCustomBindUnmarshalerElementsUri(t *testing.T) {
|
||||||
|
var s struct {
|
||||||
|
Items [2]customUnmarshalParamType `uri:"items"`
|
||||||
|
}
|
||||||
|
err := mappingByPtr(&s, formSource{"items": {"grpc:service1:auth", "rest:service2:data"}}, "uri")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "grpc", s.Items[0].Protocol)
|
||||||
|
assert.Equal(t, "service1", s.Items[0].Path)
|
||||||
|
assert.Equal(t, "auth", s.Items[0].Name)
|
||||||
|
assert.Equal(t, "rest", s.Items[1].Protocol)
|
||||||
|
assert.Equal(t, "service2", s.Items[1].Path)
|
||||||
|
assert.Equal(t, "data", s.Items[1].Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMappingArrayOfCustomBindUnmarshalerElementsForm(t *testing.T) {
|
||||||
|
var s struct {
|
||||||
|
Items [2]customUnmarshalParamType `form:"items"`
|
||||||
|
}
|
||||||
|
err := mappingByPtr(&s, formSource{"items": {"ws:chat:room1", "wss:chat:room2"}}, "form")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "ws", s.Items[0].Protocol)
|
||||||
|
assert.Equal(t, "chat", s.Items[0].Path)
|
||||||
|
assert.Equal(t, "room1", s.Items[0].Name)
|
||||||
|
assert.Equal(t, "wss", s.Items[1].Protocol)
|
||||||
|
assert.Equal(t, "chat", s.Items[1].Path)
|
||||||
|
assert.Equal(t, "room2", s.Items[1].Name)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user