diff --git a/encoder.go b/encoder.go index bf1d511..f0ed631 100644 --- a/encoder.go +++ b/encoder.go @@ -57,6 +57,13 @@ func isZero(v reflect.Value) bool { } return z case reflect.Struct: + type zero interface { + IsZero() bool + } + if v.Type().Implements(reflect.TypeOf((*zero)(nil)).Elem()) { + iz := v.MethodByName("IsZero").Call([]reflect.Value{})[0] + return iz.Interface().(bool) + } z := true for i := 0; i < v.NumField(); i++ { z = z && isZero(v.Field(i)) diff --git a/encoder_test.go b/encoder_test.go index e03b2d0..368103b 100644 --- a/encoder_test.go +++ b/encoder_test.go @@ -4,6 +4,7 @@ import ( "fmt" "reflect" "testing" + "time" ) type E1 struct { @@ -417,3 +418,48 @@ func TestRegisterEncoderCustomArrayType(t *testing.T) { encoder.Encode(s, vals) } } + +func TestRegisterEncoderStructIsZero(t *testing.T) { + type S1 struct { + SomeTime1 time.Time `schema:"tim1,omitempty"` + SomeTime2 time.Time `schema:"tim2,omitempty"` + } + + ss := []*S1{ + { + SomeTime1: time.Date(2020, 8, 4, 13, 30, 1, 0, time.UTC), + }, + } + + for s := range ss { + vals := map[string][]string{} + + encoder := NewEncoder() + encoder.RegisterEncoder(time.Time{}, func(value reflect.Value) string { + return value.Interface().(time.Time).Format(time.RFC3339Nano) + }) + + err := encoder.Encode(ss[s], vals) + if err != nil { + t.Errorf("Encoder has non-nil error: %v", err) + } + + ta, ok := vals["tim1"] + if !ok { + t.Error("expected tim1 to be present") + } + + if len(ta) != 1 { + t.Error("expected tim1 to be present") + } + + if "2020-08-04T13:30:01Z" != ta[0] { + t.Error("expected correct tim1 time") + } + + _, ok = vals["tim2"] + if ok { + t.Error("expected tim1 not to be present") + } + } +}