From 2282be059be78f9f7f70a72ca4dd3bcfe5f972ee Mon Sep 17 00:00:00 2001 From: Alexander Lokhman Date: Thu, 26 Apr 2018 15:09:34 +0100 Subject: [PATCH] Add support of pointers in form binding (#1336) * Add support of pointers in form binding * Add tests for pointer form binding --- binding/binding_test.go | 38 ++++++++++++++++++++++++++++++++++++++ binding/form_mapping.go | 6 ++++++ 2 files changed, 44 insertions(+) diff --git a/binding/binding_test.go b/binding/binding_test.go index ac826417..e29e6dfe 100644 --- a/binding/binding_test.go +++ b/binding/binding_test.go @@ -144,6 +144,15 @@ type FooBarStructForFloat64Type struct { Float64Bar float64 `form:"float64_bar" binding:"required"` } +type FooStructForStringPtrType struct { + PtrFoo *string `form:"ptr_foo"` + PtrBar *string `form:"ptr_bar" binding:"required"` +} + +type FooStructForMapPtrType struct { + PtrBar *map[string]interface{} `form:"ptr_bar"` +} + func TestBindingDefault(t *testing.T) { assert.Equal(t, Form, Default("GET", "")) assert.Equal(t, Form, Default("GET", MIMEJSON)) @@ -378,6 +387,14 @@ func TestBindingFormForType(t *testing.T) { testFormBindingForType(t, "GET", "/?float64_foo=&float64_bar=-12.34", "/?bar2=12.3", "", "", "Float64") + + testFormBindingForType(t, "POST", + "/", "/", + "ptr_bar=test", "bar2=test", "Ptr") + + testFormBindingForType(t, "GET", + "/?ptr_bar=test", "/?bar2=test", + "", "", "Ptr") } func TestBindingQuery(t *testing.T) { @@ -944,6 +961,27 @@ func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody s obj := FooStructForSliceMapType{} err := b.Bind(req, &obj) assert.Error(t, err) + case "Ptr": + obj := FooStructForStringPtrType{} + err := b.Bind(req, &obj) + assert.NoError(t, err) + assert.Nil(t, obj.PtrFoo) + assert.Equal(t, "test", *obj.PtrBar) + + obj = FooStructForStringPtrType{} + obj.PtrBar = new(string) + err = b.Bind(req, &obj) + assert.NoError(t, err) + assert.Equal(t, "test", *obj.PtrBar) + + objErr := FooStructForMapPtrType{} + err = b.Bind(req, &objErr) + assert.Error(t, err) + + obj = FooStructForStringPtrType{} + req = requestWithBody(method, badPath, badBody) + err = b.Bind(req, &obj) + assert.Error(t, err) } } diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 7c680d99..7d5c1022 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -112,6 +112,12 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V return setFloatField(val, 64, structField) case reflect.String: structField.SetString(val) + case reflect.Ptr: + if !structField.Elem().IsValid() { + structField.Set(reflect.New(structField.Type().Elem())) + } + structFieldElem := structField.Elem() + return setWithProperType(structFieldElem.Kind(), val, structFieldElem) default: return errors.New("Unknown type") }