Skip to content

Commit 15ace22

Browse files
GODRIVER-946: Add IndentExtJSON and MarshalExtJSONIndent functions (#781)
1 parent 45bc088 commit 15ace22

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

bson/marshal.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
package bson
88

99
import (
10+
"bytes"
11+
"encoding/json"
12+
1013
"go.mongodb.org/mongo-driver/bson/bsoncodec"
1114
"go.mongodb.org/mongo-driver/bson/bsonrw"
1215
"go.mongodb.org/mongo-driver/bson/bsontype"
@@ -221,3 +224,22 @@ func MarshalExtJSONAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val
221224

222225
return *sw, nil
223226
}
227+
228+
func IndentExtJSON(dst *bytes.Buffer, src []byte, prefix, indent string) error {
229+
return json.Indent(dst, src, prefix, indent)
230+
}
231+
232+
func MarshalExtJSONIndent(val interface{}, canonical, escapeHTML bool, prefix, indent string) ([]byte, error) {
233+
marshaled, err := MarshalExtJSON(val, canonical, escapeHTML)
234+
if err != nil {
235+
return nil, err
236+
}
237+
238+
var buf bytes.Buffer
239+
err = IndentExtJSON(&buf, marshaled, prefix, indent)
240+
if err != nil {
241+
return nil, err
242+
}
243+
244+
return buf.Bytes(), nil
245+
}

bson/marshal_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"fmt"
1313
"reflect"
1414
"testing"
15+
"time"
1516

1617
"github.com/google/go-cmp/cmp"
1718
"github.com/stretchr/testify/require"
@@ -302,3 +303,73 @@ func TestNullBytes(t *testing.T) {
302303
}
303304
})
304305
}
306+
307+
func TestMarshalExtJSONIndent(t *testing.T) {
308+
type indentTestCase struct {
309+
name string
310+
val interface{}
311+
expectedExtJSON string
312+
}
313+
314+
// expectedExtJSON must be written as below because single-quoted
315+
// literal strings capture undesired code formatting tabs
316+
testCases := []indentTestCase{
317+
{
318+
"empty val",
319+
struct{}{},
320+
`{}`,
321+
},
322+
{
323+
"embedded struct",
324+
struct {
325+
Embedded interface{} `json:"embedded"`
326+
Foo string `json:"foo"`
327+
}{
328+
Embedded: struct {
329+
Name string `json:"name"`
330+
Word string `json:"word"`
331+
}{
332+
Name: "test",
333+
Word: "word",
334+
},
335+
Foo: "bar",
336+
},
337+
"{\n\t\"embedded\": {\n\t\t\"name\": \"test\",\n\t\t\"word\": \"word\"\n\t},\n\t\"foo\": \"bar\"\n}",
338+
},
339+
{
340+
"date struct",
341+
struct {
342+
Foo string `json:"foo"`
343+
Date time.Time `json:"date"`
344+
}{
345+
Foo: "bar",
346+
Date: time.Date(2000, time.January, 1, 12, 0, 0, 0, time.UTC),
347+
},
348+
"{\n\t\"foo\": \"bar\",\n\t\"date\": {\n\t\t\"$date\": {\n\t\t\t\"$numberLong\": \"946728000000\"\n\t\t}\n\t}\n}",
349+
},
350+
{
351+
"float struct",
352+
struct {
353+
Foo string `json:"foo"`
354+
Float float32 `json:"float"`
355+
}{
356+
Foo: "bar",
357+
Float: 3.14,
358+
},
359+
"{\n\t\"foo\": \"bar\",\n\t\"float\": {\n\t\t\"$numberDouble\": \"3.140000104904175\"\n\t}\n}",
360+
},
361+
}
362+
363+
for _, tc := range testCases {
364+
tc := tc
365+
t.Run(tc.name, func(t *testing.T) {
366+
t.Parallel()
367+
extJSONBytes, err := MarshalExtJSONIndent(tc.val, true, false, "", "\t")
368+
assert.Nil(t, err, "Marshal indent error: %v", err)
369+
370+
expectedExtJSONBytes := []byte(tc.expectedExtJSON)
371+
372+
assert.Equal(t, expectedExtJSONBytes, extJSONBytes, "expected:\n%s\ngot:\n%s", expectedExtJSONBytes, extJSONBytes)
373+
})
374+
}
375+
}

0 commit comments

Comments
 (0)