Skip to content

Commit 6aeebdb

Browse files
committed
Add Element.StructField()
This new method returns reflect.StructField if element represents a field of a struct. It can be used for writing callbacks reading field tags for example.
1 parent 849a131 commit 6aeebdb

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

mapify.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,26 @@ type MapValue func(path string, e Element) (interface{}, error)
3131

3232
// Element represents either a map entry, field of a struct or unnamed element of a slice.
3333
type Element struct {
34-
name string
34+
name string
35+
field *reflect.StructField
3536
reflect.Value
3637
}
3738

39+
// Name returns field name of a struct, key of a map or empty string, when it represents element of a slice.
3840
func (e Element) Name() string {
3941
return e.name
4042
}
4143

44+
// StructField returns the reflect.StructField if e represents a field of a struct. If not, ok is false.
45+
func (e Element) StructField() (_ reflect.StructField, ok bool) {
46+
if e.field == nil {
47+
return reflect.StructField{}, false
48+
}
49+
50+
return *e.field, true
51+
}
52+
53+
// MapAny maps any object (struct, map, slice etc.) by converting each struct found to a map.
4254
func (i Mapper) MapAny(v interface{}) (interface{}, error) {
4355
return i.newInstance().mapAny("", v)
4456
}
@@ -89,7 +101,7 @@ func (i Mapper) mapStruct(path string, reflectValue reflect.Value) (map[string]i
89101
fieldName := field.Name
90102
fieldPath := path + "." + fieldName
91103
value := reflectValue.Field(j)
92-
element := Element{name: fieldName, Value: value}
104+
element := Element{name: fieldName, Value: value, field: &field}
93105

94106
if err := i.mapStructField(fieldPath, element, result); err != nil {
95107
return nil, err

mapify_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,34 @@ type stringError string
526526
func (d stringError) Error() string {
527527
return string(d)
528528
}
529+
530+
func TestElement_StructField(t *testing.T) {
531+
t.Run("should return struct field in callbacks", func(t *testing.T) {
532+
mapper := mapify.Mapper{
533+
Filter: func(path string, e mapify.Element) (bool, error) {
534+
assertStructField(t, "Field", e)
535+
536+
return true, nil
537+
},
538+
Rename: func(path string, e mapify.Element) (string, error) {
539+
assertStructField(t, "Field", e)
540+
541+
return e.Name(), nil
542+
},
543+
MapValue: func(path string, e mapify.Element) (interface{}, error) {
544+
assertStructField(t, "Field", e)
545+
546+
return e.Interface(), nil
547+
},
548+
}
549+
_, _ = mapper.MapAny(struct{ Field string }{})
550+
})
551+
}
552+
553+
func assertStructField(t *testing.T, fieldName string, e mapify.Element) {
554+
t.Helper()
555+
556+
field, ok := e.StructField()
557+
require.True(t, ok)
558+
assert.Equal(t, fieldName, field.Name)
559+
}

0 commit comments

Comments
 (0)