diff --git a/binder_test.go b/binder_test.go index bb22786..982491c 100644 --- a/binder_test.go +++ b/binder_test.go @@ -79,6 +79,10 @@ type TestMapIntKey struct { Map2 map[TestTypeString]TestTypeInt } +type TestMapIntKey2 struct { + Map map[int]*TestProfile +} + func TestMapToAnonymous(t *testing.T) { e := New() m := &TestAnonymous{} @@ -369,6 +373,25 @@ func TestStructMapIntKey(t *testing.T) { }, }, m) } +func TestStructMapIntKey2(t *testing.T) { + e := New() + m := &TestMapIntKey2{} + err := FormToStruct(e, m, map[string][]string{ + `map[1][address]`: {`a`}, + `map[2][address]`: {`b`}, + `map[3][address]`: {`c`}, + `map[5][address]`: {`e`}, + }, ``) + assert.NoError(t, err) + assert.Equal(t, &TestMapIntKey2{ + Map: map[int]*TestProfile{ + 1: {Address: `a`}, + 2: {Address: `b`}, + 3: {Address: `c`}, + 5: {Address: `e`}, + }, + }, m) +} type TestBinderWithConvertor struct { Options map[string]string `form_decoder:"splitKVRows:=" form_encoder:"joinKVRows"` diff --git a/binder_tostruct.go b/binder_tostruct.go index 9e218d4..40dae90 100644 --- a/binder_tostruct.go +++ b/binder_tostruct.go @@ -263,7 +263,7 @@ func (e *Echo) parseFormItem(keyNormalizer func(string) string, m interface{}, t value = value.Elem() } itemT = itemT.Elem() - index := reflect.ValueOf(name) + index := convertMapKey(tc, name) newV := value.MapIndex(index) if !newV.IsValid() { newV = reflect.New(itemT).Elem() @@ -421,6 +421,22 @@ func (e *Echo) binderValueDecode(name string, typev reflect.Type, tv reflect.Val return ErrNotImplemented } +func convertMapKey(typev reflect.Type, key string) reflect.Value { + var index reflect.Value + keyT := typev.Key() + kind := keyT.Kind() + if kind != reflect.String { + mapKey := param.AsType(kind.String(), key) + index = reflect.ValueOf(mapKey) + } else { + index = reflect.ValueOf(key) + } + if index.Type().Name() != keyT.Name() && index.CanConvert(keyT) { + index = index.Convert(keyT) + } + return index +} + func (e *Echo) setMap(logger logger.Logger, parentT reflect.Type, parentV reflect.Value, name string, value reflect.Value, typev reflect.Type, @@ -429,16 +445,7 @@ func (e *Echo) setMap(logger logger.Logger, value.Set(reflect.MakeMap(value.Type())) } value = reflect.Indirect(value) - var index reflect.Value - if typev.Key().Kind() != reflect.String { - mapKey := param.AsType(typev.Key().Kind().String(), name) - index = reflect.ValueOf(mapKey) - } else { - index = reflect.ValueOf(name) - } - if index.Type().Name() != typev.Key().Name() && index.CanConvert(typev.Key()) { - index = index.Convert(typev.Key()) - } + index := convertMapKey(typev, name) oldVal := value.MapIndex(index) if !oldVal.IsValid() { oldType := value.Type().Elem()