From d8c73c8619613a9d11ada65a27d856583126eb91 Mon Sep 17 00:00:00 2001 From: Faye Amacker <33205765+fxamacker@users.noreply.github.com> Date: Thu, 29 Dec 2022 18:35:28 -0600 Subject: [PATCH] Refactor NilContainersMode option - Moved NilContainersMode from decode.go to encode.go because it is only an encoding option. - Renamed NullForNil to NilContainerAsNull. - Renamed EmptyForNil to NilContainerAsEmpty. - Updated and added some comments. --- decode.go | 17 ----------------- encode.go | 27 +++++++++++++++++++++++---- encode_test.go | 19 ++++++++++--------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/decode.go b/decode.go index 8a91296a..c444451e 100644 --- a/decode.go +++ b/decode.go @@ -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 diff --git a/encode.go b/encode.go index 99478cd8..a2a26574 100644 --- a/encode.go +++ b/encode.go @@ -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. @@ -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). @@ -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 } @@ -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 } @@ -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 } diff --git a/encode_test.go b/encode_test.go index a0d49baf..15b4c6fb 100644 --- a/encode_test.go +++ b/encode_test.go @@ -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) { @@ -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()