diff --git a/types/dynamic/dynamic.go b/types/dynamic/dynamic.go index b8f01f2774..bb5b0d789c 100644 --- a/types/dynamic/dynamic.go +++ b/types/dynamic/dynamic.go @@ -204,8 +204,8 @@ func ExtractCustomAttributes(v interface{}, msg []byte) ([]byte, error) { return nil, err } objectStarted := false - for field, value := range anys { - _, ok := fields[field] + for _, any := range sortAnys(anys) { + _, ok := fields[any.Name] if ok { // Not a custom attribute continue @@ -216,8 +216,8 @@ func ExtractCustomAttributes(v interface{}, msg []byte) ([]byte, error) { } else { stream.WriteMore() } - stream.WriteObjectField(field) - value.WriteTo(stream) + stream.WriteObjectField(any.Name) + any.WriteTo(stream) } if !objectStarted { stream.WriteObjectStart() diff --git a/types/dynamic/dynamic_test.go b/types/dynamic/dynamic_test.go index 7ff73d3df1..425aaf0d07 100644 --- a/types/dynamic/dynamic_test.go +++ b/types/dynamic/dynamic_test.go @@ -1,6 +1,7 @@ package dynamic import ( + "encoding/json" "reflect" "testing" @@ -94,6 +95,25 @@ func (m MyType) Get(name string) (interface{}, error) { return GetField(m, name) } +func (m MyType) MarshalJSON() ([]byte, error) { + return Marshal(m) +} + +func (m *MyType) UnmarshalJSON(p []byte) error { + type __ MyType + var x __ + if err := json.Unmarshal(p, &x); err != nil { + return err + } + *m = MyType(x) + custom, err := ExtractCustomAttributes(m, p) + if err != nil { + return err + } + m.custom = custom + return nil +} + func TestExtractEmptyCustomAttributes(t *testing.T) { require := require.New(t) assert := assert.New(t) @@ -247,3 +267,14 @@ func TestQueryGovaluateComplex(t *testing.T) { require.Nil(t, err) require.Equal(t, true, result) } + +func TestMarshalUnmarshal(t *testing.T) { + data := []byte(`{"bar":null,"foo":"hello","a":10,"b":"c"}`) + var m MyType + err := json.Unmarshal(data, &m) + require.Nil(t, err) + assert.Equal(t, MyType{Foo: "hello", custom: []byte(`{"a":10,"b":"c"}`)}, m) + b, err := json.Marshal(m) + require.Nil(t, err) + assert.Equal(t, data, b) +}