Skip to content

Commit 99b3433

Browse files
kisielkelithrar
authored andcommitted
Support more types in encoder custom type zero comparison. (#98)
Fixes #97
1 parent e929b54 commit 99b3433

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

encoder.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,29 @@ func (e *Encoder) SetAliasTag(tag string) {
4040
e.cache.tag = tag
4141
}
4242

43+
func isZero(v reflect.Value) bool {
44+
switch v.Kind() {
45+
case reflect.Func:
46+
case reflect.Map, reflect.Slice:
47+
return v.IsNil() || v.Len() == 0
48+
case reflect.Array:
49+
z := true
50+
for i := 0; i < v.Len(); i++ {
51+
z = z && isZero(v.Index(i))
52+
}
53+
return z
54+
case reflect.Struct:
55+
z := true
56+
for i := 0; i < v.NumField(); i++ {
57+
z = z && isZero(v.Field(i))
58+
}
59+
return z
60+
}
61+
// Compare other types directly:
62+
z := reflect.Zero(v.Type())
63+
return v.Interface() == z.Interface()
64+
}
65+
4366
func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error {
4467
if v.Kind() == reflect.Ptr {
4568
v = v.Elem()
@@ -67,7 +90,7 @@ func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error {
6790
// Encode non-slice types and custom implementations immediately.
6891
if encFunc != nil {
6992
value := encFunc(v.Field(i))
70-
if opts.Contains("omitempty") && v.Field(i).Interface() == reflect.Zero(reflect.TypeOf(v.Field(i).Interface())).Interface() {
93+
if opts.Contains("omitempty") && isZero(v.Field(i)) {
7194
continue
7295
}
7396

encoder_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package schema
22

33
import (
4+
"fmt"
45
"reflect"
56
"testing"
67
)
@@ -330,3 +331,28 @@ func TestEncoderWithOmitempty(t *testing.T) {
330331
valNotExists(t, "f08", vals)
331332
valsExist(t, "f09", []string{"test"}, vals)
332333
}
334+
335+
func TestRegisterEncoderCustomArrayType(t *testing.T) {
336+
type CustomInt []int
337+
type S1 struct {
338+
SomeInts CustomInt `schema:",omitempty"`
339+
}
340+
341+
ss := []S1{
342+
{},
343+
{CustomInt{}},
344+
{CustomInt{1, 2, 3}},
345+
}
346+
347+
for s := range ss {
348+
vals := map[string][]string{}
349+
350+
encoder := NewEncoder()
351+
encoder.RegisterEncoder(CustomInt{}, func(value reflect.Value) string {
352+
return fmt.Sprint(value.Interface())
353+
})
354+
355+
encoder.Encode(s, vals)
356+
t.Log(vals)
357+
}
358+
}

0 commit comments

Comments
 (0)