@@ -1154,6 +1154,17 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node
|
||||
case reflect.Struct:
|
||||
path, found := structFieldPath(v, string(key.Node().Data))
|
||||
if !found {
|
||||
// If no matching struct field is found but the target implements the
|
||||
// unstable.Unmarshaler interface (and it is enabled), delegate the
|
||||
// decoding of this value to the custom unmarshaler.
|
||||
if d.unmarshalerInterface {
|
||||
if v.CanAddr() && v.Addr().CanInterface() {
|
||||
if outi, ok := v.Addr().Interface().(unstable.Unmarshaler); ok {
|
||||
return reflect.Value{}, outi.UnmarshalTOML(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise, keep previous behavior and skip until the next table.
|
||||
d.skipUntilTable = true
|
||||
break
|
||||
}
|
||||
|
||||
@@ -3998,3 +3998,45 @@ foo = "bar"`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type doc994 struct{}
|
||||
|
||||
func (d *doc994) UnmarshalTOML(value *unstable.Node) error {
|
||||
return errors.New("expected-error")
|
||||
}
|
||||
|
||||
func TestIssue994(t *testing.T) {
|
||||
var _ unstable.Unmarshaler = (*doc994)(nil)
|
||||
tomlBytes := []byte(`foo = "bar"`)
|
||||
var d doc994
|
||||
err := toml.NewDecoder(bytes.NewReader(tomlBytes)).
|
||||
EnableUnmarshalerInterface().
|
||||
Decode(&d)
|
||||
|
||||
assert.Error(t, err)
|
||||
|
||||
if err.Error() != "expected-error" {
|
||||
t.Fatalf("expected error 'expected-error', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
type doc994ok struct {
|
||||
S string
|
||||
}
|
||||
|
||||
func (d *doc994ok) UnmarshalTOML(value *unstable.Node) error {
|
||||
d.S = string(value.Data) + " from unmarshaler"
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestIssue994_OK(t *testing.T) {
|
||||
var _ unstable.Unmarshaler = (*doc994ok)(nil)
|
||||
tomlBytes := []byte(`foo = "bar"`)
|
||||
var d doc994ok
|
||||
err := toml.NewDecoder(bytes.NewReader(tomlBytes)).
|
||||
EnableUnmarshalerInterface().
|
||||
Decode(&d)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "bar from unmarshaler", d.S)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user