From ea529bbab6602db8bd9fc0746405a3687ffbd885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georg=20M=C3=BCller?= Date: Tue, 6 Feb 2024 16:18:12 +0100 Subject: [PATCH] binder: allow binding to a nil map --- bind.go | 3 +++ bind_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/bind.go b/bind.go index 6f41ce587..51f4689e7 100644 --- a/bind.go +++ b/bind.go @@ -145,6 +145,9 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri if !(isElemSliceOfStrings || isElemString || isElemInterface) { return nil } + if val.IsNil() { + val.Set(reflect.MakeMap(typ)) + } for k, v := range data { if isElemString { val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0])) diff --git a/bind_test.go b/bind_test.go index c11723303..cffccfb35 100644 --- a/bind_test.go +++ b/bind_test.go @@ -447,6 +447,18 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) { ) }) + t.Run("ok, bind to map[string]string with nil map", func(t *testing.T) { + var dest map[string]string + assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) + assert.Equal(t, + map[string]string{ + "multiple": "1", + "single": "3", + }, + dest, + ) + }) + t.Run("ok, bind to map[string][]string", func(t *testing.T) { dest := map[string][]string{} assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) @@ -459,6 +471,18 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) { ) }) + t.Run("ok, bind to map[string][]string with nil map", func(t *testing.T) { + var dest map[string][]string + assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) + assert.Equal(t, + map[string][]string{ + "multiple": {"1", "2"}, + "single": {"3"}, + }, + dest, + ) + }) + t.Run("ok, bind to map[string]interface", func(t *testing.T) { dest := map[string]interface{}{} assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) @@ -471,18 +495,41 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) { ) }) + t.Run("ok, bind to map[string]interface with nil map", func(t *testing.T) { + var dest map[string]interface{} + assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) + assert.Equal(t, + map[string]interface{}{ + "multiple": []string{"1", "2"}, + "single": []string{"3"}, + }, + dest, + ) + }) + t.Run("ok, bind to map[string]int skips", func(t *testing.T) { dest := map[string]int{} assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) assert.Equal(t, map[string]int{}, dest) }) + t.Run("ok, bind to map[string]int skips with nil map", func(t *testing.T) { + var dest map[string]int + assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) + assert.Equal(t, map[string]int(nil), dest) + }) + t.Run("ok, bind to map[string][]int skips", func(t *testing.T) { dest := map[string][]int{} assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) assert.Equal(t, map[string][]int{}, dest) }) + t.Run("ok, bind to map[string][]int skips with nil map", func(t *testing.T) { + var dest map[string][]int + assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param")) + assert.Equal(t, map[string][]int(nil), dest) + }) } func TestBindbindData(t *testing.T) {