diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 540bbbb84a..55435b9493 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -239,6 +239,11 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface()) case reflect.Map: return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface()) + case reflect.Ptr: + if !value.Elem().IsValid() { + value.Set(reflect.New(value.Type().Elem())) + } + return setWithProperType(val, value.Elem(), field) default: return errUnknownType } diff --git a/binding/form_mapping_test.go b/binding/form_mapping_test.go index 93d6a92ff8..acea8f77a7 100644 --- a/binding/form_mapping_test.go +++ b/binding/form_mapping_test.go @@ -269,6 +269,39 @@ func TestMappingStructField(t *testing.T) { assert.Equal(t, 9, s.J.I) } +func TestMappingPtrField(t *testing.T) { + type ptrStruct struct { + Key int64 `json:"key"` + } + + type ptrRequest struct { + Items []*ptrStruct `json:"items" form:"items"` + } + + var err error + + // With 0 items. + var req0 ptrRequest + err = mappingByPtr(&req0, formSource{}, "form") + assert.NoError(t, err) + assert.Empty(t, req0.Items) + + // With 1 item. + var req1 ptrRequest + err = mappingByPtr(&req1, formSource{"items": {`{"key": 1}`}}, "form") + assert.NoError(t, err) + assert.Len(t, req1.Items, 1) + assert.EqualValues(t, 1, req1.Items[0].Key) + + // With 2 items. + var req2 ptrRequest + err = mappingByPtr(&req2, formSource{"items": {`{"key": 1}`, `{"key": 2}`}}, "form") + assert.NoError(t, err) + assert.Len(t, req2.Items, 2) + assert.EqualValues(t, 1, req2.Items[0].Key) + assert.EqualValues(t, 2, req2.Items[1].Key) +} + func TestMappingMapField(t *testing.T) { var s struct { M map[string]int