Skip to content

Commit d0e4c24

Browse files
emil2kkisielk
authored andcommitted
Fix handling of empty value. (#104)
If a value is decoding into a type that implements the encoding.TextUnmarshaler interface, the decoder should use it's UnmarshalText method in all instances including an empty value. Previously, would ignore the method decoding the field as the empty value of the type.
1 parent b0e8c20 commit d0e4c24

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

Diff for: decoder.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
283283
val = values[len(values)-1]
284284
}
285285

286-
if val == "" {
287-
if d.zeroEmpty {
288-
v.Set(reflect.Zero(t))
289-
}
290-
} else if conv != nil {
286+
if conv != nil {
291287
if value := conv(val); value.IsValid() {
292288
v.Set(value.Convert(t))
293289
} else {
@@ -321,6 +317,10 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
321317
}
322318
}
323319
}
320+
} else if val == "" {
321+
if d.zeroEmpty {
322+
v.Set(reflect.Zero(t))
323+
}
324324
} else if conv := builtinConverters[t.Kind()]; conv != nil {
325325
if value := conv(val); value.IsValid() {
326326
v.Set(value.Convert(t))

Diff for: decoder_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -1737,3 +1737,33 @@ func TestTextUnmarshalerTypeSliceOfStructs(t *testing.T) {
17371737
t.Fatal("Expecting invalid path error", err)
17381738
}
17391739
}
1740+
1741+
type S22 string
1742+
1743+
func (s *S22) UnmarshalText(text []byte) error {
1744+
*s = S22("a")
1745+
return nil
1746+
}
1747+
1748+
// Test to ensure that when a field that should be decoded into a type
1749+
// implementing the encoding.TextUnmarshaler interface is set to an empty value
1750+
// that the UnmarshalText method is utilized over other methods of decoding,
1751+
// especially including simply setting the zero value.
1752+
func TestTextUnmarshalerEmpty(t *testing.T) {
1753+
data := map[string][]string{
1754+
"Value": []string{""}, // empty value
1755+
}
1756+
// Implements encoding.TextUnmarshaler, should use the type's
1757+
// UnmarshalText method.
1758+
s := struct {
1759+
Value S22
1760+
}{}
1761+
decoder := NewDecoder()
1762+
if err := decoder.Decode(&s, data); err != nil {
1763+
t.Fatal("Error while decoding:", err)
1764+
}
1765+
expected := S22("a")
1766+
if expected != s.Value {
1767+
t.Errorf("Expected %v errors, got %v", expected, s.Value)
1768+
}
1769+
}

0 commit comments

Comments
 (0)