Skip to content

Commit 18d7fe1

Browse files
lipengweialdas
authored andcommitted
Fix #1858: Add query params binding support for anonymous struct pointer filed
1 parent 2943a32 commit 18d7fe1

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

bind.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,20 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
144144
for i := 0; i < typ.NumField(); i++ {
145145
typeField := typ.Field(i)
146146
structField := val.Field(i)
147+
if typeField.Anonymous {
148+
for structField.Kind() == reflect.Ptr {
149+
structField = structField.Elem()
150+
}
151+
}
147152
if !structField.CanSet() {
148153
continue
149154
}
150155
structFieldKind := structField.Kind()
151156
inputFieldName := typeField.Tag.Get(tag)
157+
if typeField.Anonymous && structField.Kind() == reflect.Struct && inputFieldName != "" {
158+
// if anonymous struct, ignore custom tag
159+
inputFieldName = ""
160+
}
152161

153162
if inputFieldName == "" {
154163
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).

bind_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ type (
100100
Struct struct {
101101
Foo string
102102
}
103+
Bar struct {
104+
Baz int `json:"baz" query:"baz"`
105+
}
103106
)
104107

105108
func (t *Timestamp) UnmarshalParam(src string) error {
@@ -330,6 +333,48 @@ func TestBindUnmarshalParamPtr(t *testing.T) {
330333
}
331334
}
332335

336+
func TestBindUnmarshalParamAnonymousFieldPtr(t *testing.T) {
337+
e := New()
338+
req := httptest.NewRequest(http.MethodGet, "/?baz=1", nil)
339+
rec := httptest.NewRecorder()
340+
c := e.NewContext(req, rec)
341+
result := struct {
342+
*Bar
343+
}{&Bar{}}
344+
err := c.Bind(&result)
345+
if assert.NoError(t, err) {
346+
assert.Equal(t, 1, result.Baz)
347+
}
348+
}
349+
350+
func TestBindUnmarshalParamAnonymousFieldPtrNil(t *testing.T) {
351+
e := New()
352+
req := httptest.NewRequest(http.MethodGet, "/?baz=1", nil)
353+
rec := httptest.NewRecorder()
354+
c := e.NewContext(req, rec)
355+
result := struct {
356+
*Bar
357+
}{}
358+
err := c.Bind(&result)
359+
if assert.NoError(t, err) {
360+
assert.Nil(t, result.Bar)
361+
}
362+
}
363+
364+
func TestBindUnmarshalParamAnonymousFieldPtrCustomTag(t *testing.T) {
365+
e := New()
366+
req := httptest.NewRequest(http.MethodGet, `/?bar={"baz":100}&baz=1`, nil)
367+
rec := httptest.NewRecorder()
368+
c := e.NewContext(req, rec)
369+
result := struct {
370+
*Bar `json:"bar" query:"bar"`
371+
}{&Bar{}}
372+
err := c.Bind(&result)
373+
if assert.NoError(t, err) {
374+
assert.Equal(t, 1, result.Baz)
375+
}
376+
}
377+
333378
func TestBindUnmarshalTextPtr(t *testing.T) {
334379
e := New()
335380
req := httptest.NewRequest(GET, "/?ts=2016-12-06T19:09:05Z", nil)

0 commit comments

Comments
 (0)