Skip to content

Commit 0e6dc09

Browse files
committed
GODRIVER-3427 Add a global "omitempty" flag.
1 parent 3ab40de commit 0e6dc09

File tree

7 files changed

+46
-2
lines changed

7 files changed

+46
-2
lines changed

bson/bsoncodec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ type EncodeContext struct {
8888
nilSliceAsEmpty bool
8989
nilByteSliceAsEmpty bool
9090
omitZeroStruct bool
91+
omitEmpty bool
9192
useJSONStructTags bool
9293
}
9394

bson/encoder.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,21 @@ func (e *Encoder) NilByteSliceAsEmpty() {
108108
// TODO struct fields once the logic is updated to also inspect private struct fields.
109109

110110
// OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{})
111-
// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set.
111+
// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set
112+
// or the OmitEmpty() method is called.
112113
//
113114
// Note that the Encoder only examines exported struct fields when determining if a struct is the
114115
// zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty.
115116
func (e *Encoder) OmitZeroStruct() {
116117
e.ec.omitZeroStruct = true
117118
}
118119

120+
// OmitEmpty causes the Encoder to omit empty values from the marshaled BSON as the "omitempty"
121+
// struct tag option is set.
122+
func (e *Encoder) OmitEmpty() {
123+
e.ec.omitEmpty = true
124+
}
125+
119126
// UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson"
120127
// struct tag is not specified.
121128
func (e *Encoder) UseJSONStructTags() {

bson/encoder_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,19 @@ func TestEncoderConfiguration(t *testing.T) {
248248
}{},
249249
want: bsoncore.NewDocumentBuilder().Build(),
250250
},
251+
// Test that OmitZeroStruct omits empty structs from the marshaled document if
252+
// OmitEmpty is also set.
253+
{
254+
description: "OmitEmpty",
255+
configure: func(enc *Encoder) {
256+
enc.OmitZeroStruct()
257+
enc.OmitEmpty()
258+
},
259+
input: struct {
260+
Zero zeroStruct
261+
}{},
262+
want: bsoncore.NewDocumentBuilder().Build(),
263+
},
251264
// Test that UseJSONStructTags causes the Encoder to fall back to "json" struct tags if
252265
// "bson" struct tags are not available.
253266
{

bson/struct_codec.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ func (sc *structCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect
118118
}
119119
}
120120

121+
if ec.omitEmpty {
122+
desc.omitEmpty = true
123+
}
124+
121125
desc.encoder, rv, err = lookupElementEncoder(ec, desc.encoder, rv)
122126

123127
if err != nil && !errors.Is(err, errInvalidValue) {

internal/integration/client_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,19 @@ func TestClient_BSONOptions(t *testing.T) {
956956
want: &bson.D{},
957957
wantRaw: bson.Raw(bsoncore.NewDocumentBuilder().Build()),
958958
},
959+
{
960+
name: "OmitEmpty",
961+
bsonOpts: &options.BSONOptions{
962+
OmitZeroStruct: true,
963+
OmitEmpty: true,
964+
},
965+
doc: struct {
966+
X jsonTagsTest `bson:"x"`
967+
}{},
968+
decodeInto: func() interface{} { return &bson.D{} },
969+
want: &bson.D{},
970+
wantRaw: bson.Raw(bsoncore.NewDocumentBuilder().Build()),
971+
},
959972
{
960973
name: "StringifyMapKeysWithFmt",
961974
bsonOpts: &options.BSONOptions{

mongo/mongo.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ func getEncoder(
8383
if opts.OmitZeroStruct {
8484
enc.OmitZeroStruct()
8585
}
86+
if opts.OmitEmpty {
87+
enc.OmitEmpty()
88+
}
8689
if opts.StringifyMapKeysWithFmt {
8790
enc.StringifyMapKeysWithFmt()
8891
}

mongo/options/clientoptions.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,12 @@ type BSONOptions struct {
182182

183183
// OmitZeroStruct causes the driver to consider the zero value for a struct
184184
// (e.g. MyStruct{}) as empty and omit it from the marshaled BSON when the
185-
// "omitempty" struct tag option is set.
185+
// "omitempty" struct tag option or the "OmitEmpty" field is set.
186186
OmitZeroStruct bool
187187

188+
// OmitEmpty causes the driver to omit empty values from the marshaled BSON.
189+
OmitEmpty bool
190+
188191
// StringifyMapKeysWithFmt causes the driver to convert Go map keys to BSON
189192
// document field name strings using fmt.Sprint instead of the default
190193
// string conversion logic.

0 commit comments

Comments
 (0)