Skip to content

Commit

Permalink
Merge pull request #377 from fxamacker/fxamacker/refactor-nilcontaine…
Browse files Browse the repository at this point in the history
…r-encoption

Refactor NilContainersMode option
  • Loading branch information
fxamacker authored Dec 30, 2022
2 parents 75d0384 + d8c73c8 commit 3ef81e0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 30 deletions.
17 changes: 0 additions & 17 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,23 +210,6 @@ func (m IndefLengthMode) valid() bool {
return m < maxIndefLengthMode
}

// NilContainersMode specifies how to encode []Type(nil) and map[Key]Type(nil).
type NilContainersMode int

const (
// NullForNil enforces null for []Type(nil)/map[Key]Type(nil).
NullForNil NilContainersMode = iota

// EmptyForNil enforces empty map/list for []Type(nil)/map[Key]Type(nil).
EmptyForNil

maxNilContainersMode
)

func (m NilContainersMode) valid() bool {
return m < maxNilContainersMode
}

// TagsMode specifies whether to allow CBOR tags.
type TagsMode int

Expand Down
27 changes: 23 additions & 4 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,25 @@ func (bim BigIntConvertMode) valid() bool {
return bim < maxBigIntConvert
}

// NilContainersMode specifies how to encode nil slices and maps.
type NilContainersMode int

const (
// NilContainerAsNull encodes nil slices and maps as CBOR null.
// This is the default.
NilContainerAsNull NilContainersMode = iota

// NilContainerAsEmpty encodes nil slices and maps as
// empty container (CBOR bytestring, array, or map).
NilContainerAsEmpty

maxNilContainersMode
)

func (m NilContainersMode) valid() bool {
return m < maxNilContainersMode
}

// EncOptions specifies encoding options.
type EncOptions struct {
// Sort specifies sorting order.
Expand Down Expand Up @@ -292,7 +311,7 @@ type EncOptions struct {
// IndefLength specifies whether to allow indefinite length CBOR items.
IndefLength IndefLengthMode

// NilContainers specifies how to encode map[Key]Type(nil)/[]Type(nil)
// NilContainers specifies how to encode nil slices and maps.
NilContainers NilContainersMode

// TagsMd specifies whether to allow CBOR tags (major type 6).
Expand Down Expand Up @@ -795,7 +814,7 @@ func encodeFloat64(e *encoderBuffer, f64 float64) error {

func encodeByteString(e *encoderBuffer, em *encMode, v reflect.Value) error {
vk := v.Kind()
if vk == reflect.Slice && v.IsNil() && em.nilContainers == NullForNil {
if vk == reflect.Slice && v.IsNil() && em.nilContainers == NilContainerAsNull {
e.Write(cborNil)
return nil
}
Expand Down Expand Up @@ -832,7 +851,7 @@ type arrayEncodeFunc struct {
}

func (ae arrayEncodeFunc) encode(e *encoderBuffer, em *encMode, v reflect.Value) error {
if v.Kind() == reflect.Slice && v.IsNil() && em.nilContainers == NullForNil {
if v.Kind() == reflect.Slice && v.IsNil() && em.nilContainers == NilContainerAsNull {
e.Write(cborNil)
return nil
}
Expand All @@ -857,7 +876,7 @@ type mapEncodeFunc struct {
}

func (me mapEncodeFunc) encode(e *encoderBuffer, em *encMode, v reflect.Value) error {
if v.IsNil() && em.nilContainers == NullForNil {
if v.IsNil() && em.nilContainers == NilContainerAsNull {
e.Write(cborNil)
return nil
}
Expand Down
19 changes: 10 additions & 9 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2858,22 +2858,23 @@ func TestInvalidInfConvert(t *testing.T) {
}

func TestNilContainers(t *testing.T) {
nilContainersNull := EncOptions{NilContainers: NullForNil}
nilContainersEmpty := EncOptions{NilContainers: EmptyForNil}
nilContainersNull := EncOptions{NilContainers: NilContainerAsNull}
nilContainersEmpty := EncOptions{NilContainers: NilContainerAsEmpty}

testCases := []struct {
name string
v interface{}
opts EncOptions
wantCborData []byte
}{
{"map(nil) as null", map[string]string(nil), nilContainersNull, hexDecode("f6")},
{"map(nil) as empty map", map[string]string(nil), nilContainersEmpty, hexDecode("a0")},
{"map(nil) as CBOR null", map[string]string(nil), nilContainersNull, hexDecode("f6")},
{"map(nil) as CBOR empty map", map[string]string(nil), nilContainersEmpty, hexDecode("a0")},

{"slice(nil) as null", []int(nil), nilContainersNull, hexDecode("f6")},
{"slice(nil) as empty list", []int(nil), nilContainersEmpty, hexDecode("80")},
{"slice(nil) as CBOR null", []int(nil), nilContainersNull, hexDecode("f6")},
{"slice(nil) as CBOR empty array", []int(nil), nilContainersEmpty, hexDecode("80")},

{"[]byte(nil) as null", []byte(nil), nilContainersNull, hexDecode("f6")},
{"[]byte(nil) as empty bytestring", []byte(nil), nilContainersEmpty, hexDecode("40")},
{"[]byte(nil) as CBOR null", []byte(nil), nilContainersNull, hexDecode("f6")},
{"[]byte(nil) as CBOR empty bytestring", []byte(nil), nilContainersEmpty, hexDecode("40")},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
Expand Down Expand Up @@ -3355,7 +3356,7 @@ func TestEncOptions(t *testing.T) {
Time: TimeRFC3339Nano,
TimeTag: EncTagRequired,
IndefLength: IndefLengthForbidden,
NilContainers: NullForNil,
NilContainers: NilContainerAsNull,
TagsMd: TagsAllowed,
}
em, err := opts1.EncMode()
Expand Down

0 comments on commit 3ef81e0

Please sign in to comment.