unmarshal: use UnmarshalText for any type (#642)
Not only structs can implement TextUnmarshaler. Fixes #564
This commit is contained in:
@@ -560,10 +560,6 @@ func (d *decoder) handleTablePart(key ast.Iterator, v reflect.Value) (reflect.Va
|
||||
}
|
||||
|
||||
func (d *decoder) tryTextUnmarshaler(node *ast.Node, v reflect.Value) (bool, error) {
|
||||
if v.Kind() != reflect.Struct {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Special case for time, because we allow to unmarshal to it from
|
||||
// different kind of AST nodes.
|
||||
if v.Type() == timeType {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package toml_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -1822,6 +1823,30 @@ foo = "bar"`
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
type uuid [16]byte
|
||||
|
||||
func (u *uuid) UnmarshalText(text []byte) (err error) {
|
||||
// Note: the original reported issue had a more complex implementation
|
||||
// of this function. But the important part is to verify that a
|
||||
// non-struct type implementing UnmarshalText works with the unmarshal
|
||||
// process.
|
||||
placeholder := bytes.Repeat([]byte{0xAA}, 16)
|
||||
copy(u[:], placeholder)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestIssue564(t *testing.T) {
|
||||
type Config struct {
|
||||
ID uuid
|
||||
}
|
||||
|
||||
var config Config
|
||||
|
||||
err := toml.Unmarshal([]byte(`id = "0818a52b97b94768941ba1172c76cf6c"`), &config)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uuid{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, config.ID)
|
||||
}
|
||||
|
||||
//nolint:funlen
|
||||
func TestUnmarshalDecodeErrors(t *testing.T) {
|
||||
examples := []struct {
|
||||
|
||||
Reference in New Issue
Block a user