UnmarshalText fallbacks to struct unmarshaling for tables and arrays (#1026)

When a type implements encoding.TextUnmarshaler, the unmarshaler now
skips calling UnmarshalText for Array and InlineTable TOML values.
This allows types to support both:
- Simple string values via UnmarshalText
- Structured table values via field-by-field unmarshaling

Previously, UnmarshalText was called unconditionally, which prevented
proper struct unmarshaling when the TOML value was a table or array
of tables.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Pelletier
2026-01-09 13:46:38 -05:00
committed by GitHub
parent 003aa0993b
commit 4a1b05ca08
2 changed files with 126 additions and 3 deletions
+9 -3
View File
@@ -702,9 +702,15 @@ func (d *decoder) handleValue(value *unstable.Node, v reflect.Value) error {
}
}
ok, err := d.tryTextUnmarshaler(value, v)
if ok || err != nil {
return err
// Only try TextUnmarshaler for scalar types. For Array and InlineTable,
// fall through to struct/map unmarshaling to allow flexible unmarshaling
// where a type can implement UnmarshalText for string values but still
// be populated field-by-field from a table. See issue #974.
if value.Kind != unstable.Array && value.Kind != unstable.InlineTable {
ok, err := d.tryTextUnmarshaler(value, v)
if ok || err != nil {
return err
}
}
switch value.Kind {