Skip to content

Commit 1dfaf6b

Browse files
authored
Merge pull request #231 from ulucinar/fix-buildStructCacheEntry
Check inlined struct field's kind before recursively calling value.buildStructCacheEntry
2 parents 27c21c1 + 3726c80 commit 1dfaf6b

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

value/reflectcache.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ func buildStructCacheEntry(t reflect.Type, infos map[string]*FieldCacheEntry, fi
154154
if field.Type.Kind() == reflect.Ptr {
155155
e = field.Type.Elem()
156156
}
157-
buildStructCacheEntry(e, infos, append(fieldPath, field.Index))
157+
if e.Kind() == reflect.Struct {
158+
buildStructCacheEntry(e, infos, append(fieldPath, field.Index))
159+
}
158160
continue
159161
}
160162
info := &FieldCacheEntry{JsonName: jsonName, isOmitEmpty: isOmitempty, fieldPath: append(fieldPath, field.Index), fieldType: field.Type}

value/reflectcache_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,76 @@ func TestToUnstructured(t *testing.T) {
7777
})
7878
}
7979
}
80+
81+
func TestTypeReflectEntryOf(t *testing.T) {
82+
testString := ""
83+
tests := map[string]struct {
84+
arg interface{}
85+
want *TypeReflectCacheEntry
86+
}{
87+
"StructWithStringField": {
88+
arg: struct {
89+
F1 string `json:"f1"`
90+
}{},
91+
want: &TypeReflectCacheEntry{
92+
structFields: map[string]*FieldCacheEntry{
93+
"f1": {
94+
JsonName: "f1",
95+
fieldPath: [][]int{{0}},
96+
fieldType: reflect.TypeOf(testString),
97+
TypeEntry: &TypeReflectCacheEntry{},
98+
},
99+
},
100+
orderedStructFields: []*FieldCacheEntry{
101+
{
102+
JsonName: "f1",
103+
fieldPath: [][]int{{0}},
104+
fieldType: reflect.TypeOf(testString),
105+
TypeEntry: &TypeReflectCacheEntry{},
106+
},
107+
},
108+
},
109+
},
110+
"StructWith*StringFieldOmitempty": {
111+
arg: struct {
112+
F1 *string `json:"f1,omitempty"`
113+
}{},
114+
want: &TypeReflectCacheEntry{
115+
structFields: map[string]*FieldCacheEntry{
116+
"f1": {
117+
JsonName: "f1",
118+
isOmitEmpty: true,
119+
fieldPath: [][]int{{0}},
120+
fieldType: reflect.TypeOf(&testString),
121+
TypeEntry: &TypeReflectCacheEntry{},
122+
},
123+
},
124+
orderedStructFields: []*FieldCacheEntry{
125+
{
126+
JsonName: "f1",
127+
isOmitEmpty: true,
128+
fieldPath: [][]int{{0}},
129+
fieldType: reflect.TypeOf(&testString),
130+
TypeEntry: &TypeReflectCacheEntry{},
131+
},
132+
},
133+
},
134+
},
135+
"StructWithInlinedField": {
136+
arg: struct {
137+
F1 string `json:",inline"`
138+
}{},
139+
want: &TypeReflectCacheEntry{
140+
structFields: map[string]*FieldCacheEntry{},
141+
orderedStructFields: []*FieldCacheEntry{},
142+
},
143+
},
144+
}
145+
for name, tt := range tests {
146+
t.Run(name, func(t *testing.T) {
147+
if got := TypeReflectEntryOf(reflect.TypeOf(tt.arg)); !reflect.DeepEqual(got, tt.want) {
148+
t.Errorf("TypeReflectEntryOf() = %v, want %v", got, tt.want)
149+
}
150+
})
151+
}
152+
}

0 commit comments

Comments
 (0)