Skip to content

Commit

Permalink
fixes from upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed Sep 1, 2020
1 parent 35b4e06 commit 4fafd08
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
11 changes: 11 additions & 0 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,17 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
}
v = v.Elem()
}

// alloc embedded structs
if v.Type().Kind() == reflect.Struct {
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
if field.Type().Kind() == reflect.Ptr && field.IsNil() && v.Type().Field(i).Anonymous == true {
field.Set(reflect.New(field.Type().Elem()))
}
}
}

v = v.FieldByName(name)
}
// Don't even bother for unexported fields.
Expand Down
39 changes: 39 additions & 0 deletions decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1968,3 +1968,42 @@ func TestTextUnmarshalerEmpty(t *testing.T) {
t.Errorf("Expected %v errors, got %v", expected, s.Value)
}
}

type S23n struct {
F2 string `schema:"F2"`
F3 string `schema:"F3"`
}

type S23e struct {
*S23n
F1 string `schema:"F1"`
}

type S23 []*S23e

func TestUnmashalPointerToEmbedded(t *testing.T) {
data := map[string][]string{
"A.0.F2": {"raw a"},
"A.0.F3": {"raw b"},
}

// Implements encoding.TextUnmarshaler, should not throw invalid path
// error.
s := struct {
Value S23 `schema:"A"`
}{}
decoder := NewDecoder()

if err := decoder.Decode(&s, data); err != nil {
t.Fatal("Error while decoding:", err)
}

expected := S23{
&S23e{
S23n: &S23n{"raw a", "raw b"},
},
}
if !reflect.DeepEqual(expected, s.Value) {
t.Errorf("Expected %v errors, got %v", expected, s.Value)
}
}
7 changes: 7 additions & 0 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,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))
Expand Down
46 changes: 46 additions & 0 deletions encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"reflect"
"testing"
"time"
)

type E1 struct {
Expand Down Expand Up @@ -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")
}
}
}

0 comments on commit 4fafd08

Please sign in to comment.