Skip to content

Commit 40e395c

Browse files
committed
added heednull option for json encoding
1 parent ce58a39 commit 40e395c

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

src/encoding/json/encode.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ import (
7171
// false, 0, a nil pointer, a nil interface value, and any empty array,
7272
// slice, map, or string.
7373
//
74+
// The "heednull" option specifies that if the field is a slice or map
75+
// of nil value, then the value encoded will be [] or {} respectively (instead
76+
// of "null"). If both "heednull" and "omitempty" are present, then "heednull" is
77+
// ignored. If the field is not a slice or map, "heednull" does nothing.
78+
//
7479
// As a special case, if the field tag is "-", the field is always omitted.
7580
// Note that a field with name "-" can still be generated using the tag "-,".
7681
//
@@ -656,7 +661,18 @@ FieldLoop:
656661
e.WriteString(f.nameNonEsc)
657662
}
658663
opts.quoted = f.quoted
659-
f.encoder(e, fv, opts)
664+
665+
if f.heedNull {
666+
if f.typ.Kind() == reflect.Slice && fv.IsNil() {
667+
e.WriteString("[]")
668+
} else if f.typ.Kind() == reflect.Map && fv.IsNil() {
669+
e.WriteString("{}")
670+
} else {
671+
f.encoder(e, fv, opts)
672+
}
673+
} else {
674+
f.encoder(e, fv, opts)
675+
}
660676
}
661677
if next == '{' {
662678
e.WriteString("{}")
@@ -1039,6 +1055,7 @@ type field struct {
10391055
index []int
10401056
typ reflect.Type
10411057
omitEmpty bool
1058+
heedNull bool
10421059
quoted bool
10431060

10441061
encoder encoderFunc
@@ -1156,6 +1173,7 @@ func typeFields(t reflect.Type) []field {
11561173
index: index,
11571174
typ: ft,
11581175
omitEmpty: opts.Contains("omitempty"),
1176+
heedNull: !opts.Contains("omitempty") && opts.Contains("heednull"),
11591177
quoted: quoted,
11601178
}
11611179
field.nameBytes = []byte(field.name)

src/encoding/json/encode_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ type Optionals struct {
4141

4242
Str struct{} `json:"str"`
4343
Sto struct{} `json:"sto,omitempty"`
44+
45+
Slh []string `json:"slh,heednull"`
46+
Slb []string `json:"slb,omitempty,heednull"`
47+
48+
Mh map[string]interface{} `json:"mh,heednull"`
49+
Mb map[string]interface{} `json:"mb,omitempty,heednull"`
4450
}
4551

4652
var optionalsExpected = `{
@@ -52,7 +58,9 @@ var optionalsExpected = `{
5258
"br": false,
5359
"ur": 0,
5460
"str": {},
55-
"sto": {}
61+
"sto": {},
62+
"slh": [],
63+
"mh": {}
5664
}`
5765

5866
func TestOmitEmpty(t *testing.T) {

0 commit comments

Comments
 (0)