Skip to content

Commit 563bd26

Browse files
committed
Added support for omitempty:"true"
1 parent 0419463 commit 563bd26

File tree

3 files changed

+86
-61
lines changed

3 files changed

+86
-61
lines changed

codec/reflectcodec/struct_fielder.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,18 @@ const (
1818

1919
// TagValue is the value the tag must have to be serialized.
2020
TagValue = "true"
21+
22+
// TagValue is the value the tag must have to be serialized, this variant
23+
// includes Omit Empty
24+
TagWithOmitEmptyValue = "true,omitempty"
2125
)
2226

2327
var _ StructFielder = (*structFielder)(nil)
2428

2529
type FieldDesc struct {
2630
Index int
2731
MaxSliceLen uint32
32+
OmitEmpty bool
2833
}
2934

3035
// StructFielder handles discovery of serializable fields in a struct.
@@ -83,9 +88,16 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error)
8388
// Serialize/Deserialize field if it has
8489
// any tag with the right value
8590
captureField := false
91+
omitEmpty := false
8692
for _, tag := range s.tags {
87-
if field.Tag.Get(tag) == TagValue {
93+
switch tagValue := field.Tag.Get(tag); tagValue {
94+
case TagValue:
95+
captureField = true
96+
case TagWithOmitEmptyValue:
8897
captureField = true
98+
omitEmpty = true
99+
}
100+
if captureField {
89101
break
90102
}
91103
}
@@ -107,6 +119,7 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error)
107119
serializedFields = append(serializedFields, FieldDesc{
108120
Index: i,
109121
MaxSliceLen: maxSliceLen,
122+
OmitEmpty: omitEmpty,
110123
})
111124
}
112125
s.serializedFieldIndices[t] = serializedFields // cache result

codec/reflectcodec/type_codec.go

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,16 @@ func (c *genericCodec) Size(value interface{}) (int, error) {
9292
}
9393

9494
metaValue := reflect.ValueOf(value)
95-
switch valueKind := metaValue.Kind(); valueKind {
96-
case reflect.Ptr:
95+
if metaValue.Kind() == reflect.Ptr {
9796
metaValue = metaValue.Elem()
9897
}
9998

100-
size, _, err := c.size(metaValue)
99+
size, _, err := c.size(metaValue, false)
101100
return size, err
102101
}
103102

104103
// size returns the size of the value along with whether the value is constant sized.
105-
func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
104+
func (c *genericCodec) size(value reflect.Value, omitEmpty bool) (int, bool, error) {
106105
switch valueKind := value.Kind(); valueKind {
107106
case reflect.Uint8:
108107
return wrappers.ByteLen, true, nil
@@ -125,15 +124,22 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
125124
case reflect.String:
126125
return wrappers.StringLen(value.String()), false, nil
127126
case reflect.Ptr:
128-
if value.IsNil() {
129-
return magicBytesPtrPrefixSize, false, nil
127+
if omitEmpty {
128+
if value.IsNil() {
129+
return magicBytesPtrPrefixSize, false, nil
130+
}
131+
size, _, err := c.size(value.Elem(), omitEmpty)
132+
if err != nil {
133+
return 0, false, err
134+
}
135+
return magicBytesPtrPrefixSize + size, false, nil
130136
}
131-
size, _, err := c.size(value.Elem())
132-
if err != nil {
133-
return 0, false, err
137+
138+
if value.IsNil() { // Can't marshal nil (except nil slices *or* if omitEmpty)
139+
return 0, false, errMarshalNil
134140
}
135-
return magicBytesPtrPrefixSize + size, false, nil
136141

142+
return c.size(value.Elem(), omitEmpty)
137143
case reflect.Interface:
138144
if value.IsNil() {
139145
// Can't marshal nil interfaces (but nil slices are fine)
@@ -142,7 +148,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
142148
underlyingValue := value.Interface()
143149
underlyingType := reflect.TypeOf(underlyingValue)
144150
prefixSize := c.typer.PrefixSize(underlyingType)
145-
valueSize, _, err := c.size(value.Elem())
151+
valueSize, _, err := c.size(value.Elem(), omitEmpty)
146152
if err != nil {
147153
return 0, false, err
148154
}
@@ -154,7 +160,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
154160
return wrappers.IntLen, false, nil
155161
}
156162

157-
size, constSize, err := c.size(value.Index(0))
163+
size, constSize, err := c.size(value.Index(0), omitEmpty)
158164
if err != nil {
159165
return 0, false, err
160166
}
@@ -166,7 +172,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
166172
}
167173

168174
for i := 1; i < numElts; i++ {
169-
innerSize, _, err := c.size(value.Index(i))
175+
innerSize, _, err := c.size(value.Index(i), omitEmpty)
170176
if err != nil {
171177
return 0, false, err
172178
}
@@ -180,7 +186,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
180186
return 0, true, nil
181187
}
182188

183-
size, constSize, err := c.size(value.Index(0))
189+
size, constSize, err := c.size(value.Index(0), omitEmpty)
184190
if err != nil {
185191
return 0, false, err
186192
}
@@ -192,7 +198,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
192198
}
193199

194200
for i := 1; i < numElts; i++ {
195-
innerSize, _, err := c.size(value.Index(i))
201+
innerSize, _, err := c.size(value.Index(i), omitEmpty)
196202
if err != nil {
197203
return 0, false, err
198204
}
@@ -211,7 +217,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
211217
constSize = true
212218
)
213219
for _, fieldDesc := range serializedFields {
214-
innerSize, innerConstSize, err := c.size(value.Field(fieldDesc.Index))
220+
innerSize, innerConstSize, err := c.size(value.Field(fieldDesc.Index), fieldDesc.OmitEmpty)
215221
if err != nil {
216222
return 0, false, err
217223
}
@@ -226,11 +232,11 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
226232
return wrappers.IntLen, false, nil
227233
}
228234

229-
keySize, keyConstSize, err := c.size(iter.Key())
235+
keySize, keyConstSize, err := c.size(iter.Key(), omitEmpty)
230236
if err != nil {
231237
return 0, false, err
232238
}
233-
valueSize, valueConstSize, err := c.size(iter.Value())
239+
valueSize, valueConstSize, err := c.size(iter.Value(), omitEmpty)
234240
if err != nil {
235241
return 0, false, err
236242
}
@@ -245,7 +251,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
245251
totalValueSize = valueSize
246252
)
247253
for iter.Next() {
248-
valueSize, _, err := c.size(iter.Value())
254+
valueSize, _, err := c.size(iter.Value(), omitEmpty)
249255
if err != nil {
250256
return 0, false, err
251257
}
@@ -259,7 +265,7 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
259265
totalKeySize = keySize
260266
)
261267
for iter.Next() {
262-
keySize, _, err := c.size(iter.Key())
268+
keySize, _, err := c.size(iter.Key(), omitEmpty)
263269
if err != nil {
264270
return 0, false, err
265271
}
@@ -270,11 +276,11 @@ func (c *genericCodec) size(value reflect.Value) (int, bool, error) {
270276
default:
271277
totalSize := wrappers.IntLen + keySize + valueSize
272278
for iter.Next() {
273-
keySize, _, err := c.size(iter.Key())
279+
keySize, _, err := c.size(iter.Key(), omitEmpty)
274280
if err != nil {
275281
return 0, false, err
276282
}
277-
valueSize, _, err := c.size(iter.Value())
283+
valueSize, _, err := c.size(iter.Value(), omitEmpty)
278284
if err != nil {
279285
return 0, false, err
280286
}
@@ -295,18 +301,17 @@ func (c *genericCodec) MarshalInto(value interface{}, p *wrappers.Packer) error
295301
}
296302

297303
metaValue := reflect.ValueOf(value)
298-
switch valueKind := metaValue.Kind(); valueKind {
299-
case reflect.Ptr:
304+
if metaValue.Kind() == reflect.Ptr {
300305
metaValue = metaValue.Elem()
301306
}
302307

303-
return c.marshal(metaValue, p, c.maxSliceLen)
308+
return c.marshal(metaValue, p, c.maxSliceLen, false)
304309
}
305310

306311
// marshal writes the byte representation of [value] to [p]
307312
// [value]'s underlying value must not be a nil pointer or interface
308313
// c.lock should be held for the duration of this function
309-
func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSliceLen uint32) error {
314+
func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSliceLen uint32, omitEmpty bool) error {
310315
switch valueKind := value.Kind(); valueKind {
311316
case reflect.Uint8:
312317
p.PackByte(uint8(value.Uint()))
@@ -339,15 +344,20 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
339344
p.PackBool(value.Bool())
340345
return p.Err
341346
case reflect.Ptr:
342-
if value.IsNil() {
343-
p.PackFixedBytes(MagicBytesPtrNil)
344-
return p.Err
345-
}
346-
p.PackFixedBytes(MagicBytesPtr)
347-
if p.Err != nil {
348-
return p.Err
347+
if omitEmpty {
348+
if value.IsNil() {
349+
p.PackFixedBytes(MagicBytesPtrNil)
350+
return p.Err
351+
}
352+
p.PackFixedBytes(MagicBytesPtr)
353+
if p.Err != nil {
354+
return p.Err
355+
}
356+
} else if value.IsNil() {
357+
return errMarshalNil
349358
}
350-
return c.marshal(value.Elem(), p, c.maxSliceLen)
359+
360+
return c.marshal(value.Elem(), p, c.maxSliceLen, omitEmpty)
351361
case reflect.Interface:
352362
if value.IsNil() { // Can't marshal nil (except nil slices)
353363
return errMarshalNil
@@ -357,7 +367,7 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
357367
if err := c.typer.PackPrefix(p, underlyingType); err != nil {
358368
return err
359369
}
360-
if err := c.marshal(value.Elem(), p, c.maxSliceLen); err != nil {
370+
if err := c.marshal(value.Elem(), p, c.maxSliceLen, omitEmpty); err != nil {
361371
return err
362372
}
363373
return p.Err
@@ -387,7 +397,7 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
387397
return p.Err
388398
}
389399
for i := 0; i < numElts; i++ { // Process each element in the slice
390-
if err := c.marshal(value.Index(i), p, c.maxSliceLen); err != nil {
400+
if err := c.marshal(value.Index(i), p, c.maxSliceLen, omitEmpty); err != nil {
391401
return err
392402
}
393403
}
@@ -407,7 +417,7 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
407417
)
408418
}
409419
for i := 0; i < numElts; i++ { // Process each element in the array
410-
if err := c.marshal(value.Index(i), p, c.maxSliceLen); err != nil {
420+
if err := c.marshal(value.Index(i), p, c.maxSliceLen, omitEmpty); err != nil {
411421
return err
412422
}
413423
}
@@ -418,7 +428,7 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
418428
return err
419429
}
420430
for _, fieldDesc := range serializedFields { // Go through all fields of this struct that are serialized
421-
if err := c.marshal(value.Field(fieldDesc.Index), p, fieldDesc.MaxSliceLen); err != nil { // Serialize the field and write to byte array
431+
if err := c.marshal(value.Field(fieldDesc.Index), p, fieldDesc.MaxSliceLen, fieldDesc.OmitEmpty); err != nil { // Serialize the field and write to byte array
422432
return err
423433
}
424434
}
@@ -449,7 +459,7 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
449459
startOffset := p.Offset
450460
endOffset := p.Offset
451461
for i, key := range keys {
452-
if err := c.marshal(key, p, c.maxSliceLen); err != nil {
462+
if err := c.marshal(key, p, c.maxSliceLen, omitEmpty); err != nil {
453463
return err
454464
}
455465
if p.Err != nil {
@@ -482,7 +492,7 @@ func (c *genericCodec) marshal(value reflect.Value, p *wrappers.Packer, maxSlice
482492
}
483493

484494
// serialize and pack value
485-
if err := c.marshal(value.MapIndex(key.key), p, c.maxSliceLen); err != nil {
495+
if err := c.marshal(value.MapIndex(key.key), p, c.maxSliceLen, omitEmpty); err != nil {
486496
return err
487497
}
488498
}
@@ -507,7 +517,7 @@ func (c *genericCodec) Unmarshal(bytes []byte, dest interface{}) error {
507517
if destPtr.Kind() != reflect.Ptr {
508518
return errNeedPointer
509519
}
510-
if err := c.unmarshal(&p, destPtr.Elem(), c.maxSliceLen); err != nil {
520+
if err := c.unmarshal(&p, destPtr.Elem(), c.maxSliceLen, false); err != nil {
511521
return err
512522
}
513523
if p.Offset != len(bytes) {
@@ -522,7 +532,7 @@ func (c *genericCodec) Unmarshal(bytes []byte, dest interface{}) error {
522532

523533
// Unmarshal from p.Bytes into [value]. [value] must be addressable.
524534
// c.lock should be held for the duration of this function
525-
func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSliceLen uint32) error {
535+
func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSliceLen uint32, omitEmpty bool) error {
526536
switch value.Kind() {
527537
case reflect.Uint8:
528538
value.SetUint(uint64(p.UnpackByte()))
@@ -609,7 +619,7 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
609619
value.Set(reflect.MakeSlice(value.Type(), numElts, numElts))
610620
// Unmarshal each element into the appropriate index of the slice
611621
for i := 0; i < numElts; i++ {
612-
if err := c.unmarshal(p, value.Index(i), c.maxSliceLen); err != nil {
622+
if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, omitEmpty); err != nil {
613623
return fmt.Errorf("couldn't unmarshal slice element: %w", err)
614624
}
615625
}
@@ -627,7 +637,7 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
627637
return nil
628638
}
629639
for i := 0; i < numElts; i++ {
630-
if err := c.unmarshal(p, value.Index(i), c.maxSliceLen); err != nil {
640+
if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, omitEmpty); err != nil {
631641
return fmt.Errorf("couldn't unmarshal array element: %w", err)
632642
}
633643
}
@@ -644,7 +654,7 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
644654
return err
645655
}
646656
// Unmarshal into the struct
647-
if err := c.unmarshal(p, intfImplementor, c.maxSliceLen); err != nil {
657+
if err := c.unmarshal(p, intfImplementor, c.maxSliceLen, omitEmpty); err != nil {
648658
return fmt.Errorf("couldn't unmarshal interface: %w", err)
649659
}
650660
// And assign the filled struct to the value
@@ -658,7 +668,7 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
658668
}
659669
// Go through the fields and umarshal into them
660670
for _, fieldDesc := range serializedFieldIndices {
661-
if err := c.unmarshal(p, value.Field(fieldDesc.Index), fieldDesc.MaxSliceLen); err != nil {
671+
if err := c.unmarshal(p, value.Field(fieldDesc.Index), fieldDesc.MaxSliceLen, fieldDesc.OmitEmpty); err != nil {
662672
return fmt.Errorf("couldn't unmarshal struct: %w", err)
663673
}
664674
}
@@ -669,11 +679,13 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
669679
// Create a new pointer to a new value of the underlying type
670680
v := reflect.New(t)
671681
// Fill the value
672-
if bytes.Equal(MagicBytesPtrNil, p.UnpackIfMatches(MagicBytesPtrNil, MagicBytesPtr)) {
673-
// Nil
674-
return nil
682+
if omitEmpty {
683+
if bytes.Equal(MagicBytesPtrNil, p.UnpackIfMatches(MagicBytesPtrNil, MagicBytesPtr)) {
684+
// Nil
685+
return nil
686+
}
675687
}
676-
if err := c.unmarshal(p, v.Elem(), c.maxSliceLen); err != nil {
688+
if err := c.unmarshal(p, v.Elem(), c.maxSliceLen, omitEmpty); err != nil {
677689
return fmt.Errorf("couldn't unmarshal pointer: %w", err)
678690
}
679691
// Assign to the top-level struct's member
@@ -708,7 +720,7 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
708720

709721
keyStartOffset := p.Offset
710722

711-
if err := c.unmarshal(p, mapKey, c.maxSliceLen); err != nil {
723+
if err := c.unmarshal(p, mapKey, c.maxSliceLen, omitEmpty); err != nil {
712724
return fmt.Errorf("couldn't unmarshal map key (%s): %w", mapKeyType, err)
713725
}
714726

@@ -726,7 +738,7 @@ func (c *genericCodec) unmarshal(p *wrappers.Packer, value reflect.Value, maxSli
726738

727739
// Get the value
728740
mapValue := reflect.New(mapValueType).Elem()
729-
if err := c.unmarshal(p, mapValue, c.maxSliceLen); err != nil {
741+
if err := c.unmarshal(p, mapValue, c.maxSliceLen, omitEmpty); err != nil {
730742
return fmt.Errorf("couldn't unmarshal map value for key %s: %w", mapKey, err)
731743
}
732744

0 commit comments

Comments
 (0)