Skip to content

Commit 42f9f05

Browse files
committed
Implement MapValue
1 parent 990bb0b commit 42f9f05

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

defaults.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ func acceptAllFields(string, Element) bool {
1010
func noRename(_ string, e Element) string {
1111
return e.Name()
1212
}
13+
14+
func interfaceValue(_ string, e Element) interface{} {
15+
return e.Interface()
16+
}

mapify.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type MapValue func(path string, e Element) interface{}
2828
// Element represents either a map entry, field of a struct or unnamed element of a slice.
2929
type Element struct {
3030
name string
31+
reflect.Value
3132
}
3233

3334
func (e Element) Name() string {
@@ -62,6 +63,10 @@ func (i Instance) newInstance() Instance {
6263
i.Rename = noRename
6364
}
6465

66+
if i.MapValue == nil {
67+
i.MapValue = interfaceValue
68+
}
69+
6570
return i
6671
}
6772

@@ -79,12 +84,13 @@ func (i Instance) mapStruct(path string, reflectValue reflect.Value) map[string]
7984

8085
fieldName := field.Name
8186
fieldPath := path + "." + fieldName
82-
element := Element{name: fieldName}
87+
value := reflectValue.Field(j)
88+
element := Element{name: fieldName, Value: value}
8389

8490
if i.Filter(fieldPath, element) {
85-
value := reflectValue.Field(j)
8691
renamed := i.Rename(fieldPath, element)
87-
result[renamed] = i.mapAny(fieldPath, value.Interface())
92+
mappedValue := i.MapValue(fieldPath, Element{name: element.Name(), Value: value})
93+
result[renamed] = i.mapAny(fieldPath, mappedValue)
8894
}
8995
}
9096

mapify_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,27 @@ func TestFilter(t *testing.T) {
397397
},
398398
v)
399399
})
400+
401+
t.Run("should filter by value", func(t *testing.T) {
402+
instance := mapify.Instance{
403+
Filter: func(path string, e mapify.Element) bool {
404+
return e.String() == "keep it"
405+
},
406+
}
407+
// when
408+
v := instance.MapAny(
409+
struct{ Field1, Field2 string }{
410+
Field1: "keep it",
411+
Field2: "omit this",
412+
},
413+
)
414+
// then
415+
assert.Equal(t,
416+
map[string]interface{}{
417+
"Field1": "keep it",
418+
},
419+
v)
420+
})
400421
}
401422

402423
func TestRename(t *testing.T) {
@@ -420,3 +441,55 @@ func TestRename(t *testing.T) {
420441
v)
421442
})
422443
}
444+
445+
func TestMapValue(t *testing.T) {
446+
mappedValue := "str"
447+
448+
t.Run("should map struct field", func(t *testing.T) {
449+
instance := mapify.Instance{
450+
MapValue: func(path string, e mapify.Element) interface{} {
451+
if e.Name() == "Field1" {
452+
return mappedValue
453+
}
454+
455+
return e.Interface()
456+
},
457+
}
458+
s := struct{ Field1, Field2 int }{
459+
Field1: 1, Field2: 2,
460+
}
461+
// when
462+
v := instance.MapAny(s)
463+
// then
464+
assert.Equal(t,
465+
map[string]interface{}{
466+
"Field1": mappedValue,
467+
"Field2": s.Field2,
468+
},
469+
v)
470+
})
471+
472+
t.Run("should map struct field by path", func(t *testing.T) {
473+
instance := mapify.Instance{
474+
MapValue: func(path string, e mapify.Element) interface{} {
475+
if path == ".Field1" {
476+
return mappedValue
477+
}
478+
479+
return e.Interface()
480+
},
481+
}
482+
s := struct{ Field1, Field2 int }{
483+
Field1: 1, Field2: 2,
484+
}
485+
// when
486+
v := instance.MapAny(s)
487+
// then
488+
assert.Equal(t,
489+
map[string]interface{}{
490+
"Field1": mappedValue,
491+
"Field2": s.Field2,
492+
},
493+
v)
494+
})
495+
}

0 commit comments

Comments
 (0)