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) {
|
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
|
// Special case for time, because we allow to unmarshal to it from
|
||||||
// different kind of AST nodes.
|
// different kind of AST nodes.
|
||||||
if v.Type() == timeType {
|
if v.Type() == timeType {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package toml_test
|
package toml_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1822,6 +1823,30 @@ foo = "bar"`
|
|||||||
require.Error(t, err)
|
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
|
//nolint:funlen
|
||||||
func TestUnmarshalDecodeErrors(t *testing.T) {
|
func TestUnmarshalDecodeErrors(t *testing.T) {
|
||||||
examples := []struct {
|
examples := []struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user