Skip to content

Commit f638c84

Browse files
committed
binder: allow binding to a nil map
1 parent 60fc2fb commit f638c84

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

bind.go

+3
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
138138
// You are better off binding to struct but there are user who want this map feature. Source of data for these cases are:
139139
// params,query,header,form as these sources produce string values, most of the time slice of strings, actually.
140140
if typ.Kind() == reflect.Map && typ.Key().Kind() == reflect.String {
141+
if val.IsNil() {
142+
val.Set(reflect.MakeMap(typ))
143+
}
141144
k := typ.Elem().Kind()
142145
isElemInterface := k == reflect.Interface
143146
isElemString := k == reflect.String

bind_test.go

+48
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,18 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) {
447447
)
448448
})
449449

450+
t.Run("ok, bind to map[string]string with nil map", func(t *testing.T) {
451+
var dest map[string]string
452+
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
453+
assert.Equal(t,
454+
map[string]string{
455+
"multiple": "1",
456+
"single": "3",
457+
},
458+
dest,
459+
)
460+
})
461+
450462
t.Run("ok, bind to map[string][]string", func(t *testing.T) {
451463
dest := map[string][]string{}
452464
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
@@ -459,6 +471,18 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) {
459471
)
460472
})
461473

474+
t.Run("ok, bind to map[string][]string with nil map", func(t *testing.T) {
475+
var dest map[string][]string
476+
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
477+
assert.Equal(t,
478+
map[string][]string{
479+
"multiple": {"1", "2"},
480+
"single": {"3"},
481+
},
482+
dest,
483+
)
484+
})
485+
462486
t.Run("ok, bind to map[string]interface", func(t *testing.T) {
463487
dest := map[string]interface{}{}
464488
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
@@ -471,18 +495,42 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) {
471495
)
472496
})
473497

498+
t.Run("ok, bind to map[string]interface with nil map", func(t *testing.T) {
499+
var dest map[string]interface{}
500+
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
501+
assert.Equal(t,
502+
map[string]interface{}{
503+
"multiple": []string{"1", "2"},
504+
"single": []string{"3"},
505+
},
506+
dest,
507+
)
508+
})
509+
474510
t.Run("ok, bind to map[string]int skips", func(t *testing.T) {
475511
dest := map[string]int{}
476512
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
477513
assert.Equal(t, map[string]int{}, dest)
478514
})
479515

516+
t.Run("ok, bind to map[string]int skips with nil map", func(t *testing.T) {
517+
var dest map[string]int
518+
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
519+
assert.Equal(t, map[string]int{}, dest)
520+
})
521+
480522
t.Run("ok, bind to map[string][]int skips", func(t *testing.T) {
481523
dest := map[string][]int{}
482524
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
483525
assert.Equal(t, map[string][]int{}, dest)
484526
})
485527

528+
t.Run("ok, bind to map[string][]int skips with nil map", func(t *testing.T) {
529+
var dest map[string][]int
530+
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
531+
assert.Equal(t, map[string][]int{}, dest)
532+
})
533+
486534
}
487535

488536
func TestBindbindData(t *testing.T) {

0 commit comments

Comments
 (0)