Skip to content

Commit 802e9e5

Browse files
committed
Slice of pointers to structs mapping support
1 parent c805814 commit 802e9e5

2 files changed

Lines changed: 31 additions & 10 deletions

File tree

mapify.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ func (e Element) StructField() (_ reflect.StructField, ok bool) {
5656

5757
// MapAny maps any object (struct, map, slice etc.) by converting each struct found to a map.
5858
//
59-
// * for struct the returned type will be map[string]interface{}
60-
// * for slice of structs the returned type will be []map[string]interface{}
59+
// - for struct the returned type will be map[string]interface{}
60+
// - for slice of structs the returned type will be []map[string]interface{}
6161
func (i Mapper) MapAny(v interface{}) (interface{}, error) {
6262
return i.newInstance().mapAny("", v)
6363
}
@@ -198,10 +198,11 @@ func (i Mapper) mapElement(fieldPath string, element Element, result map[string]
198198
}
199199

200200
func (i Mapper) mapSlice(path string, reflectValue reflect.Value) (_ interface{}, err error) {
201-
kind := reflectValue.Type().Elem().Kind()
201+
genericType := reflectValue.Type().Elem()
202+
kind := genericType.Kind()
202203

203-
switch kind {
204-
case reflect.Struct:
204+
switch {
205+
case kind == reflect.Struct || (kind == reflect.Ptr && genericType.Elem().Kind() == reflect.Struct):
205206
shouldConvert, err := i.ShouldConvert(path, reflectValue)
206207
if err != nil {
207208
return nil, fmt.Errorf("ShouldConvert failed: %w", err)
@@ -221,8 +222,8 @@ func (i Mapper) mapSlice(path string, reflectValue reflect.Value) (_ interface{}
221222
}
222223

223224
return slice, nil
224-
case reflect.Map:
225-
if reflectValue.Type().Elem().Key().Kind() != reflect.String {
225+
case kind == reflect.Map:
226+
if genericType.Key().Kind() != reflect.String {
226227
return reflectValue.Interface(), nil
227228
}
228229

@@ -245,8 +246,8 @@ func (i Mapper) mapSlice(path string, reflectValue reflect.Value) (_ interface{}
245246
}
246247

247248
return slice, nil
248-
case reflect.Slice:
249-
sliceElem := reflectValue.Type().Elem().Elem()
249+
case kind == reflect.Slice:
250+
sliceElem := genericType.Elem()
250251

251252
if sliceElem.Kind() == reflect.Struct ||
252253
(sliceElem.Kind() == reflect.Map && sliceElem.Key().Kind() == reflect.String) {

mapify_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import (
88
"reflect"
99
"testing"
1010

11-
"github.com/elgopher/mapify"
1211
"github.com/stretchr/testify/assert"
1312
"github.com/stretchr/testify/require"
13+
14+
"github.com/elgopher/mapify"
1415
)
1516

1617
func TestMapper_MapAny(t *testing.T) {
@@ -218,6 +219,25 @@ func TestMapper_MapAny(t *testing.T) {
218219
assert.Equal(t, expected, actual)
219220
})
220221

222+
t.Run("should map a slice of pointers to struct", func(t *testing.T) {
223+
type structWithField struct{ Field string }
224+
s := []*structWithField{
225+
{Field: "value1"},
226+
{Field: "value2"},
227+
}
228+
actual, err := mapper.MapAny(s)
229+
require.NoError(t, err)
230+
expected := []map[string]interface{}{
231+
{
232+
"Field": s[0].Field,
233+
},
234+
{
235+
"Field": s[1].Field,
236+
},
237+
}
238+
assert.Equal(t, expected, actual)
239+
})
240+
221241
t.Run("should map slice of slices of structs", func(t *testing.T) {
222242
type structWithField struct{ Field string }
223243
s := [][]structWithField{

0 commit comments

Comments
 (0)