Skip to content

Commit 27dcf7e

Browse files
committed
fix(generic): honor mapstructure tags during realization
1 parent 0c194eb commit 27dcf7e

2 files changed

Lines changed: 44 additions & 14 deletions

File tree

filter/generic/generalizer/map.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ func (g *MapGeneralizer) Realize(obj any, typ reflect.Type) (any, error) {
6868
obj = removeClass(obj)
6969
}
7070
newobj := reflect.New(typ).Interface()
71-
err := mapstructure.Decode(obj, newobj)
71+
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
72+
Result: newobj,
73+
TagName: "mapstructure",
74+
})
75+
if err != nil {
76+
return nil, perrors.Errorf("creating map decoder failed, %v", err)
77+
}
78+
79+
err = decoder.Decode(obj)
7280
if err != nil {
7381
return nil, perrors.Errorf("realizing map failed, %v", err)
7482
}
@@ -249,7 +257,7 @@ func mapKey(key reflect.Value) any {
249257
// setInMap sets the struct into the map using the tag or the name of the struct as the key
250258
func setInMap(m map[string]any, structField reflect.StructField, value any) (result map[string]any) {
251259
result = m
252-
if tagName := structField.Tag.Get("m"); tagName == "" {
260+
if tagName := structField.Tag.Get("mapstructure"); tagName == "" {
253261
result[toUnexport(structField.Name)] = value
254262
} else {
255263
result[tagName] = value

filter/generic/generalizer/map_test.go

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,25 @@ import (
3535
)
3636

3737
type testPlainObj struct {
38-
AaAa string `m:"aaAa"`
38+
AaAa string `mapstructure:"aaAa"`
3939
BaBa string
4040
CaCa struct {
4141
AaAa string
42-
BaBa string `m:"baBa"`
42+
BaBa string `mapstructure:"baBa"`
4343
XxYy struct {
44-
xxXx string `m:"xxXx"`
45-
Xx string `m:"xx"`
46-
} `m:"xxYy"`
47-
} `m:"caCa"`
44+
xxXx string `mapstructure:"xxXx"`
45+
Xx string `mapstructure:"xx"`
46+
} `mapstructure:"xxYy"`
47+
} `mapstructure:"caCa"`
4848
DaDa time.Time
4949
EeEe int
5050
}
5151

52+
type testMapstructureTagObj struct {
53+
UserID string `mapstructure:"user_id"`
54+
Name string
55+
}
56+
5257
func TestObjToMap(t *testing.T) {
5358
obj := &testPlainObj{}
5459
obj.AaAa = "1"
@@ -71,20 +76,37 @@ func TestObjToMap(t *testing.T) {
7176
assert.Equal(t, 100, m["eeEe"].(int))
7277
}
7378

79+
func TestMapstructureTagRoundTrip(t *testing.T) {
80+
original := testMapstructureTagObj{
81+
UserID: "42",
82+
Name: "alice",
83+
}
84+
85+
generalized, err := mockMapGeneralizer.Generalize(original)
86+
require.NoError(t, err)
87+
generalizedMap, ok := generalized.(map[string]any)
88+
require.True(t, ok)
89+
assert.Equal(t, "42", generalizedMap["user_id"])
90+
91+
realized, err := mockMapGeneralizer.Realize(generalized, reflect.TypeOf(original))
92+
require.NoError(t, err)
93+
assert.Equal(t, original, realized)
94+
}
95+
7496
type testStruct struct {
7597
AaAa string
76-
BaBa string `m:"baBa"`
98+
BaBa string `mapstructure:"baBa"`
7799
XxYy struct {
78-
xxXx string `m:"xxXx"`
79-
Xx string `m:"xx"`
80-
} `m:"xxYy"`
100+
xxXx string `mapstructure:"xxXx"`
101+
Xx string `mapstructure:"xx"`
102+
} `mapstructure:"xxYy"`
81103
}
82104

83105
func TestObjToMap_Slice(t *testing.T) {
84106
var testData struct {
85-
AaAa string `m:"aaAa"`
107+
AaAa string `mapstructure:"aaAa"`
86108
BaBa string
87-
CaCa []testStruct `m:"caCa"`
109+
CaCa []testStruct `mapstructure:"caCa"`
88110
}
89111
testData.AaAa = "1"
90112
testData.BaBa = "1"

0 commit comments

Comments
 (0)