diff --git a/decoder.go b/decoder.go index ed85641..16f012c 100644 --- a/decoder.go +++ b/decoder.go @@ -326,7 +326,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values // Try to get a converter for the element type. conv := d.cache.converter(elemT) - if conv == nil { + if conv == nil && !m.IsValid { conv = builtinConverters[elemT.Kind()] if conv == nil { // As we are not dealing with slice of structs here, we don't need to check if the type diff --git a/decoder_test.go b/decoder_test.go index 4f3b72a..7690cbf 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -18,6 +18,8 @@ type IntAlias int type rudeBool bool +type sliceID [2]byte + func (id *rudeBool) UnmarshalText(text []byte) error { value := string(text) switch { @@ -31,6 +33,14 @@ func (id *rudeBool) UnmarshalText(text []byte) error { return nil } +func (id *sliceID) UnmarshalText(text []byte) error { + if len(text) != 2 { + return errors.New("value must 2 bytes length") + } + copy(id[:], text) + return nil +} + // All cases we want to cover, in a nutshell. type S1 struct { F01 int `schema:"f1"` @@ -54,6 +64,10 @@ type S1 struct { F19 *rudeBool `schema:"f19"` F20 []rudeBool `schema:"f20"` F21 []*rudeBool `schema:"f21"` + F22 sliceID `schema:"f22"` + F23 *sliceID `schema:"f23"` + F24 []sliceID `schema:"f24"` + F25 []*sliceID `schema:"f25"` } type S2 struct { @@ -101,6 +115,10 @@ func TestAll(t *testing.T) { "f19": {"nope"}, "f20": {"nope", "yup"}, "f21": {"yup", "nope"}, + "f22": {"A1"}, + "f23": {"A2"}, + "f24": {"A3", "A4"}, + "f25": {"A5", "A6"}, } f2 := 2 f41, f42 := 41, 42 @@ -172,6 +190,10 @@ func TestAll(t *testing.T) { F19: &f153, F20: []rudeBool{f153, f152}, F21: []*rudeBool{&f152, &f153}, + F22: sliceID{'A', '1'}, + F23: &sliceID{'A', '2'}, + F24: []sliceID{{'A', '3'}, {'A', '4'}}, + F25: []*sliceID{{'A', '5'}, {'A', '6'}}, } s := &S1{} @@ -386,6 +408,26 @@ func TestAll(t *testing.T) { } else if !reflect.DeepEqual(s.F21, e.F21) { t.Errorf("f21: expected %v, got %v", e.F21, s.F21) } + if s.F22 != e.F22 { + t.Errorf("f22: expected %v, got %v", e.F22, s.F22) + } + if *s.F23 != *e.F23 { + t.Errorf("f23: expected %v, got %v", *e.F23, *s.F23) + } + if s.F24 == nil { + t.Errorf("f24: nil") + } else if len(s.F24) != len(e.F24) { + t.Errorf("f24: expected %v, got %v", e.F24, s.F24) + } else if !reflect.DeepEqual(s.F24, e.F24) { + t.Errorf("f24: expected %v, got %v", e.F24, s.F24) + } + if s.F25 == nil { + t.Errorf("f25: nil") + } else if len(s.F25) != len(e.F25) { + t.Errorf("f25: expected length %d, got %d", len(e.F25), len(s.F25)) + } else if !reflect.DeepEqual(s.F25, e.F25) { + t.Errorf("f25: expected %v, got %v", e.F25, s.F25) + } } func BenchmarkAll(b *testing.B) {