From c529f78b059af3e4d503941a156d761f62338687 Mon Sep 17 00:00:00 2001 From: Christian Stewart Date: Thu, 18 Jul 2024 19:15:44 -0700 Subject: [PATCH] feat: add MarshalSlice Signed-off-by: Christian Stewart --- json/marshal.go | 18 ++++++++++++++++++ json/marshal_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/json/marshal.go b/json/marshal.go index 27d9f841..50fe2e32 100644 --- a/json/marshal.go +++ b/json/marshal.go @@ -60,6 +60,24 @@ func (c MarshalerConfig) Marshal(m Marshaler) ([]byte, error) { return buf.Bytes(), nil } +// MarshalSlice marshals a slice of Marshalers into a JSON array. +func (c MarshalerConfig) MarshalSlice(ms []Marshaler) ([]byte, error) { + var buf bytes.Buffer + s := NewMarshalState(c, NewJsonStream(&buf)) + s.WriteArrayStart() + for i, m := range ms { + if i > 0 { + s.WriteMore() + } + m.MarshalProtoJSON(s) + } + s.WriteArrayEnd() + if err := s.Err(); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + // MarshalState is the internal state of the Marshaler. type MarshalState struct { inner *JsonStream diff --git a/json/marshal_test.go b/json/marshal_test.go index d2949169..4b90f682 100644 --- a/json/marshal_test.go +++ b/json/marshal_test.go @@ -178,3 +178,35 @@ func TestMarshaler(t *testing.T) { testMarshal(t, func(s *MarshalState) { s.WriteDuration(testDuration.Truncate(100000000)) }, `"3723.100s"`) testMarshal(t, func(s *MarshalState) { s.WriteDuration(testDuration.Truncate(1000000000)) }, `"3723s"`) } + +type testMarshaler struct { + value int +} + +func (m *testMarshaler) MarshalProtoJSON(s *MarshalState) { + s.WriteObjectStart() + s.WriteObjectField("value") + s.WriteInt32(int32(m.value)) + s.WriteObjectEnd() +} + +func TestMarshalSlice(t *testing.T) { + testSlice := []Marshaler{ + &testMarshaler{value: 1}, + &testMarshaler{value: 2}, + &testMarshaler{value: 3}, + } + + expected := `[{"value":1},{"value":2},{"value":3}]` + + config := DefaultMarshalerConfig + + result, err := config.MarshalSlice(testSlice) + if err != nil { + t.Errorf("MarshalSlice returned an error: %v", err) + } + + if string(result) != expected { + t.Errorf("MarshalSlice result does not match expected.\nGot: %s\nExpected: %s", string(result), expected) + } +}