Skip to content

Commit 26d59e8

Browse files
authored
Data: add json marshal/unmarshal to data.Frames type (#638)
1 parent 9a83358 commit 26d59e8

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

data/frame.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,25 @@ func (f *Frame) MarshalJSON() ([]byte, error) {
7575
//swagger:model
7676
type Frames []*Frame
7777

78+
func (frames *Frames) MarshalJSON() ([]byte, error) {
79+
cfg := jsoniter.ConfigCompatibleWithStandardLibrary
80+
stream := cfg.BorrowStream(nil)
81+
defer cfg.ReturnStream(stream)
82+
83+
writeDataFrames(frames, stream)
84+
if stream.Error != nil {
85+
return nil, stream.Error
86+
}
87+
88+
return append([]byte(nil), stream.Buffer()...), nil
89+
}
90+
91+
// UnmarshalJSON allows unmarshalling Frame from JSON.
92+
func (frames *Frames) UnmarshalJSON(b []byte) error {
93+
iter := jsoniter.ParseBytes(jsoniter.ConfigDefault, b)
94+
return readDataFramesJSON(frames, iter)
95+
}
96+
7897
// AppendRow adds a new row to the Frame by appending to each element of vals to
7998
// the corresponding Field in the data.
8099
// The Frame's Fields must be initialized or AppendRow will panic.

data/frame_json.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,18 @@ func readDataFrameJSON(frame *Frame, iter *jsoniter.Iterator) error {
247247
return iter.Error
248248
}
249249

250+
func readDataFramesJSON(frames *Frames, iter *jsoniter.Iterator) error {
251+
for iter.ReadArray() {
252+
frame := &Frame{}
253+
iter.ReadVal(frame)
254+
if iter.Error != nil {
255+
return iter.Error
256+
}
257+
*frames = append(*frames, frame)
258+
}
259+
return nil
260+
}
261+
250262
func readFrameData(iter *jsoniter.Iterator, frame *Frame) error {
251263
for l2Field := iter.ReadObject(); l2Field != ""; l2Field = iter.ReadObject() {
252264
switch l2Field {
@@ -848,6 +860,17 @@ func writeDataFrameData(frame *Frame, stream *jsoniter.Stream) {
848860
stream.WriteObjectEnd()
849861
}
850862

863+
func writeDataFrames(frames *Frames, stream *jsoniter.Stream) {
864+
if frames == nil {
865+
return
866+
}
867+
stream.WriteArrayStart()
868+
for _, frame := range *frames {
869+
stream.WriteVal(frame)
870+
}
871+
stream.WriteArrayEnd()
872+
}
873+
851874
// ArrowBufferToJSON writes a frame to JSON
852875
// NOTE: the format should be considered experimental until grafana 8 is released.
853876
func ArrowBufferToJSON(b []byte, include FrameInclude) ([]byte, error) {

data/frame_json_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,21 @@ func TestFieldTypeToJSON(t *testing.T) {
115115
require.JSONEq(t, string(orig), string(second))
116116
}
117117

118+
func TestJSONFrames(t *testing.T) {
119+
frames := data.Frames{goldenDF()}
120+
b, err := json.Marshal(frames)
121+
require.NoError(t, err)
122+
123+
var rFrames data.Frames
124+
125+
err = json.Unmarshal(b, &rFrames)
126+
require.NoError(t, err)
127+
128+
if diff := cmp.Diff(frames, rFrames, data.FrameTestCompareOptions()...); diff != "" {
129+
t.Errorf("Result mismatch (-want +got):\n%s", diff)
130+
}
131+
}
132+
118133
func BenchmarkFrameToJSON(b *testing.B) {
119134
f := goldenDF()
120135
b.ReportAllocs()

0 commit comments

Comments
 (0)