mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-14 12:12:12 +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 {
|
||||
for i, s := range vals {
|
||||
err := setWithProperType(s, value.Index(i), field)
|
||||
if err != nil {
|
||||
return err
|
||||
elementValue := value.Index(i)
|
||||
if isSet, err := trySetCustom(s, elementValue); isSet {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err := setWithProperType(s, elementValue, field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -635,3 +635,65 @@ func TestMappingCustomArrayForm(t *testing.T) {
|
||||
expected, _ := convertTo(val)
|
||||
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