Skip to content

Commit bb6cd83

Browse files
authored
Add embedded field support to dynamic.Marshal. (#1001)
This commit fixes a bug in dynamic.Marshal where embedded fields were not dealt with correctly. Signed-off-by: Eric Chlebek <eric@sensu.io>
1 parent 81474b7 commit bb6cd83

3 files changed

Lines changed: 59 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ in `sensuctl` with optional timezone. Stores the field as unix epoch time.
2626
### Fixed
2727
- Fixed required flags in `sensuctl` so requirements are enforced.
2828

29+
### Fixed
30+
- Add support for embedded fields to dynamic.Marshal.
31+
2932
## [2.0.0-alpha.16] - 2018-02-07
3033
### Added
3134
- Add an e2e test for proxy check requests.

types/dynamic/encoding.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,21 @@ func getJSONFields(v reflect.Value, addressOfAttrs *byte) map[string]structField
150150
continue
151151
}
152152
}
153+
// if the field is embedded, flatten it out
154+
if sf.Field.Anonymous {
155+
var attrAddr *byte
156+
if x, ok := sf.Value.Interface().(AttrGetter); ok {
157+
attrs := x.GetExtendedAttributes()
158+
if len(attrs) > 0 {
159+
attrAddr = &attrs[0]
160+
}
161+
}
162+
fields := getJSONFields(sf.Value, attrAddr)
163+
for k, v := range fields {
164+
result[k] = v
165+
}
166+
continue
167+
}
153168
// sf is a valid JSON field.
154169
result[sf.JSONName] = sf
155170
}

types/dynamic/encoding_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,44 @@ func TestGetJSONStructField(t *testing.T) {
147147
assert.Equal("validEmpty", field.JSONName)
148148
assert.Equal(false, field.OmitEmpty)
149149
}
150+
151+
type Embedded struct {
152+
Bar string `json:"bar"`
153+
Attrs []byte `json:"-"`
154+
}
155+
156+
func (e *Embedded) GetExtendedAttributes() []byte {
157+
return e.Attrs
158+
}
159+
160+
func (e *Embedded) SetExtendedAttributes(b []byte) {
161+
e.Attrs = b
162+
}
163+
164+
type EmbeddedTest struct {
165+
Foo string `json:"foo"`
166+
Embedded
167+
Baz string `json:"baz"`
168+
}
169+
170+
func TestMarshalUnmarshalEmbedded(t *testing.T) {
171+
test := &EmbeddedTest{
172+
Foo: "foo",
173+
Embedded: Embedded{
174+
Bar: "bar",
175+
},
176+
Baz: "baz",
177+
}
178+
179+
require.NoError(t, SetField(test, "extended", true))
180+
181+
b, err := Marshal(test)
182+
require.NoError(t, err)
183+
184+
assert.JSONEq(t, `{"bar":"bar","baz":"baz","foo":"foo","extended":true}`, string(b))
185+
186+
var result EmbeddedTest
187+
require.NoError(t, Unmarshal(b, &result))
188+
189+
require.Equal(t, test, &result)
190+
}

0 commit comments

Comments
 (0)