diff --git a/marshal.go b/marshal.go index a1d7010..1444006 100644 --- a/marshal.go +++ b/marshal.go @@ -1,6 +1,7 @@ package toml import ( + "bytes" "errors" "fmt" "reflect" @@ -224,24 +225,15 @@ func valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) { } } -/* -Unmarshal parses the TOML-encoded data and stores the result in the value -pointed to by v. Behavior is similar to the Go json encoder, except that there -is no concept of an Unmarshaler interface or UnmarshalTOML function for -sub-structs, and currently only definite types can be unmarshaled to (i.e. no -`interface{}`). -*/ -func Unmarshal(data []byte, v interface{}) error { +// Unmarshal attempts to unmarshal the TomlTree into a Go struct pointed by v. +// Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for +// sub-structs, and only definite types can be unmarshaled. +func (t *TomlTree) Unmarshal(v interface{}) error { mtype := reflect.TypeOf(v) if mtype.Kind() != reflect.Ptr || mtype.Elem().Kind() != reflect.Struct { return errors.New("Only a pointer to struct can be unmarshaled from TOML") } - t, err := Load(string(data)) - if err != nil { - return err - } - sval, err := valueFromTree(mtype.Elem(), t) if err != nil { return err @@ -250,6 +242,19 @@ func Unmarshal(data []byte, v interface{}) error { return nil } +// Unmarshal parses the TOML-encoded data and stores the result in the value +// pointed to by v. Behavior is similar to the Go json encoder, except that there +// is no concept of an Unmarshaler interface or UnmarshalTOML function for +// sub-structs, and currently only definite types can be unmarshaled to (i.e. no +// `interface{}`). +func Unmarshal(data []byte, v interface{}) error { + t, err := LoadReader(bytes.NewReader(data)) + if err != nil { + return err + } + return t.Unmarshal(v) +} + // Convert toml tree to marshal struct or map, using marshal type func valueFromTree(mtype reflect.Type, tval *TomlTree) (reflect.Value, error) { if mtype.Kind() == reflect.Ptr { diff --git a/marshal_test.go b/marshal_test.go index 891222e..aef4d7f 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -177,6 +177,23 @@ func TestDocUnmarshal(t *testing.T) { } } +func TestDocPartialUnmarshal(t *testing.T) { + result := testDocSubs{} + + tree, _ := LoadFile("marshal_test.toml") + subTree := tree.Get("subdoc").(*TomlTree) + err := subTree.Unmarshal(&result) + expected := docData.Subdocs + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(result, expected) { + resStr, _ := json.MarshalIndent(result, "", " ") + expStr, _ := json.MarshalIndent(expected, "", " ") + t.Errorf("Bad partial unmartial: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr) + } +} + type tomlTypeCheckTest struct { name string item interface{}