diff --git a/decoder.go b/decoder.go index 16ece12..5352a90 100644 --- a/decoder.go +++ b/decoder.go @@ -283,11 +283,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values val = values[len(values)-1] } - if val == "" { - if d.zeroEmpty { - v.Set(reflect.Zero(t)) - } - } else if conv != nil { + if conv != nil { if value := conv(val); value.IsValid() { v.Set(value.Convert(t)) } else { @@ -321,6 +317,10 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values } } } + } else if val == "" { + if d.zeroEmpty { + v.Set(reflect.Zero(t)) + } } else if conv := builtinConverters[t.Kind()]; conv != nil { if value := conv(val); value.IsValid() { v.Set(value.Convert(t)) diff --git a/decoder_test.go b/decoder_test.go index ac4898a..ee839e9 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -1737,3 +1737,33 @@ func TestTextUnmarshalerTypeSliceOfStructs(t *testing.T) { t.Fatal("Expecting invalid path error", err) } } + +type S22 string + +func (s *S22) UnmarshalText(text []byte) error { + *s = S22("a") + return nil +} + +// Test to ensure that when a field that should be decoded into a type +// implementing the encoding.TextUnmarshaler interface is set to an empty value +// that the UnmarshalText method is utilized over other methods of decoding, +// especially including simply setting the zero value. +func TestTextUnmarshalerEmpty(t *testing.T) { + data := map[string][]string{ + "Value": []string{""}, // empty value + } + // Implements encoding.TextUnmarshaler, should use the type's + // UnmarshalText method. + s := struct { + Value S22 + }{} + decoder := NewDecoder() + if err := decoder.Decode(&s, data); err != nil { + t.Fatal("Error while decoding:", err) + } + expected := S22("a") + if expected != s.Value { + t.Errorf("Expected %v errors, got %v", expected, s.Value) + } +}