Skip to content

Commit

Permalink
Address feedbacks
Browse files Browse the repository at this point in the history
Signed-off-by: Vu Dinh <[email protected]>
  • Loading branch information
dinhxuanvu committed Jan 3, 2024
1 parent 0d142f9 commit 96d9a46
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 32 deletions.
60 changes: 34 additions & 26 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,19 @@ func (m NilContainersMode) valid() bool {
type OmitEmptyMode int

const (
// OmitEmptyV1 specifies that the field should be omitted from the encoding
// if the field has an empty value, defined as false, 0, a nil pointer, a nil
// interface value, and any empty array, slice, map, or string.
// This behavior is the same with the current "v1" encoding/json library in go.
OmitEmptyV1 OmitEmptyMode = 1

maxOmitEmptyMode = 2
// OmitEmptyCBORValue specifies that fields tagged with "omitempty" should be
// omitted from encoding if the field would be encoded as an empty CBOR value,
// such as CBOR false, 0, 0.0, nil, empty byte, empty string, empty array,
// empty struct or empty map.
OmitEmptyCBORValue OmitEmptyMode = iota

// OmitEmptyGoValue specifies that fields tagged with "omitempty" should be
// omitted from encoding if the field has an empty Go value, defined as false, 0, a nil pointer,
// a nil interface value, and any empty array, slice, map, or string.
// This behavior is the same as the current (aka v1) encoding/json package included in Go.
OmitEmptyGoValue

maxOmitEmptyMode
)

func (om OmitEmptyMode) valid() bool {
Expand Down Expand Up @@ -526,6 +532,7 @@ func (opts EncOptions) encMode() (*encMode, error) {
indefLength: opts.IndefLength,
nilContainers: opts.NilContainers,
tagsMd: opts.TagsMd,
omitEmpty: opts.OmitEmpty,
}
return &em, nil
}
Expand Down Expand Up @@ -626,7 +633,7 @@ func putEncoderBuffer(e *encoderBuffer) {
}

type encodeFunc func(e *encoderBuffer, em *encMode, v reflect.Value) error
type isEmptyFunc func(v reflect.Value) (empty bool, err error)
type isEmptyFunc func(em *encMode, v reflect.Value) (empty bool, err error)

var (
cborFalse = []byte{0xf4}
Expand Down Expand Up @@ -1125,16 +1132,13 @@ func encodeStruct(e *encoderBuffer, em *encMode, v reflect.Value) (err error) {
}
}
if f.omitEmpty {
empty, err := f.ief(fv)
empty, err := f.ief(em, fv)
if err != nil {
putEncoderBuffer(kve)
return err
}
if empty {
// If the emptyMode is set to 1 and the field is a struct, preserve the field name
if !(em.omitEmpty == OmitEmptyV1 && f.typ.Kind() != reflect.Struct) {
continue
}
continue
}
}

Expand Down Expand Up @@ -1429,52 +1433,56 @@ func getEncodeIndirectValueFunc(t reflect.Type) encodeFunc {
}
}

func alwaysNotEmpty(_ reflect.Value) (empty bool, err error) {
func alwaysNotEmpty(em *encMode, _ reflect.Value) (empty bool, err error) {
return false, nil
}

Check failure on line 1438 in encode.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'em' seems to be unused, consider removing or renaming it as _ (revive)

func isEmptyBool(v reflect.Value) (bool, error) {
func isEmptyBool(em *encMode, v reflect.Value) (bool, error) {
return !v.Bool(), nil
}

Check failure on line 1442 in encode.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'em' seems to be unused, consider removing or renaming it as _ (revive)

func isEmptyInt(v reflect.Value) (bool, error) {
func isEmptyInt(em *encMode, v reflect.Value) (bool, error) {
return v.Int() == 0, nil
}

Check failure on line 1446 in encode.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'em' seems to be unused, consider removing or renaming it as _ (revive)

func isEmptyUint(v reflect.Value) (bool, error) {
func isEmptyUint(em *encMode, v reflect.Value) (bool, error) {
return v.Uint() == 0, nil
}

Check failure on line 1450 in encode.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'em' seems to be unused, consider removing or renaming it as _ (revive)

func isEmptyFloat(v reflect.Value) (bool, error) {
func isEmptyFloat(em *encMode, v reflect.Value) (bool, error) {
return v.Float() == 0.0, nil
}

Check failure on line 1454 in encode.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'em' seems to be unused, consider removing or renaming it as _ (revive)

func isEmptyString(v reflect.Value) (bool, error) {
func isEmptyString(em *encMode, v reflect.Value) (bool, error) {
return v.Len() == 0, nil
}

Check failure on line 1458 in encode.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'em' seems to be unused, consider removing or renaming it as _ (revive)

func isEmptySlice(v reflect.Value) (bool, error) {
func isEmptySlice(em *encMode, v reflect.Value) (bool, error) {
return v.Len() == 0, nil
}

func isEmptyMap(v reflect.Value) (bool, error) {
func isEmptyMap(em *encMode, v reflect.Value) (bool, error) {
return v.Len() == 0, nil
}

func isEmptyPtr(v reflect.Value) (bool, error) {
func isEmptyPtr(em *encMode, v reflect.Value) (bool, error) {
return v.IsNil(), nil
}

func isEmptyIntf(v reflect.Value) (bool, error) {
func isEmptyIntf(em *encMode, v reflect.Value) (bool, error) {
return v.IsNil(), nil
}

func isEmptyStruct(v reflect.Value) (bool, error) {
func isEmptyStruct(em *encMode, v reflect.Value) (bool, error) {
structType, err := getEncodingStructType(v.Type())
if err != nil {
return false, err
}

if em.omitEmpty == OmitEmptyGoValue {
return false, nil
}

if structType.toArray {
return len(structType.fields) == 0, nil
}
Expand All @@ -1501,7 +1509,7 @@ func isEmptyStruct(v reflect.Value) (bool, error) {
}
}

empty, err := f.ief(fv)
empty, err := f.ief(em, fv)
if err != nil {
return false, err
}
Expand All @@ -1512,7 +1520,7 @@ func isEmptyStruct(v reflect.Value) (bool, error) {
return true, nil
}

func isEmptyBinaryMarshaler(v reflect.Value) (bool, error) {
func isEmptyBinaryMarshaler(em *encMode, v reflect.Value) (bool, error) {
m, ok := v.Interface().(encoding.BinaryMarshaler)
if !ok {
pv := reflect.New(v.Type())
Expand Down
30 changes: 24 additions & 6 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1131,8 +1131,25 @@ func TestOmitEmptyMode(t *testing.T) {
}

v := T{}
// {"b": false, "ui": 0, "i":0, "f": 0, "s": "", "slc": null, "m": {}, "p": nil, "intf": nil, "str": {}, "stro": {}}
want := []byte{

// {"b": false, "ui": 0, "i":0, "f": 0, "s": "", "slc": nil, "m": nil, "p": nil, "intf": nil, "str": {}, "stro": {}}
want_govalue := []byte{
0xab,
0x61, 0x62, 0xf4,
0x62, 0x75, 0x69, 0x00,
0x61, 0x69, 0x00,
0x61, 0x66, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x61, 0x73, 0x60,
0x63, 0x73, 0x6c, 0x63, 0xf6,
0x61, 0x6d, 0xf6,
0x61, 0x70, 0xf6,
0x64, 0x69, 0x6e, 0x74, 0x66, 0xf6,
0x63, 0x73, 0x74, 0x72, 0xa0,
0x64, 0x73, 0x74, 0x72, 0x6F, 0xa0,
}

// {"b": false, "ui": 0, "i":0, "f": 0, "s": "", "slc": nil, "m": nil, "p": nil, "intf": nil, "str": nil, "stro": nil}
want_cborvalue := []byte{
0xaa,
0x61, 0x62, 0xf4,
0x62, 0x75, 0x69, 0x00,
Expand All @@ -1143,13 +1160,14 @@ func TestOmitEmptyMode(t *testing.T) {
0x61, 0x6d, 0xf6,
0x61, 0x70, 0xf6,
0x64, 0x69, 0x6e, 0x74, 0x66, 0xf6,
0x63, 0x73, 0x74, 0x72,
0xa0,
0x63, 0x73, 0x74, 0x72, 0xa0,
}

em, _ := EncOptions{OmitEmpty: OmitEmptyV1}.EncMode()
em_govalue, _ := EncOptions{OmitEmpty: OmitEmptyGoValue}.EncMode()
em_cborvalue, _ := EncOptions{OmitEmpty: OmitEmptyCBORValue}.EncMode()
dm, _ := DecOptions{}.DecMode()
testRoundTrip(t, []roundTripTest{{"default values", v, want}}, em, dm)
testRoundTrip(t, []roundTripTest{{"OmitEmptyGoValue default values", v, want_govalue}}, em_govalue, dm)
testRoundTrip(t, []roundTripTest{{"OmitEmptyCBORValue values", v, want_cborvalue}}, em_cborvalue, dm)
}

func TestOmitEmptyForNestedStruct(t *testing.T) {
Expand Down

0 comments on commit 96d9a46

Please sign in to comment.