@@ -1154,6 +1154,17 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node
|
|||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
path, found := structFieldPath(v, string(key.Node().Data))
|
path, found := structFieldPath(v, string(key.Node().Data))
|
||||||
if !found {
|
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
|
d.skipUntilTable = true
|
||||||
break
|
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