Marshal into empty interface{} (#433)
Allows to marshal a TOML document into an empty `interface{}`, resulting
in a `map[string]interface{}`.
Fixes #432
This commit is contained in:
@@ -76,6 +76,7 @@ var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
|
|||||||
var localDateType = reflect.TypeOf(LocalDate{})
|
var localDateType = reflect.TypeOf(LocalDate{})
|
||||||
var localTimeType = reflect.TypeOf(LocalTime{})
|
var localTimeType = reflect.TypeOf(LocalTime{})
|
||||||
var localDateTimeType = reflect.TypeOf(LocalDateTime{})
|
var localDateTimeType = reflect.TypeOf(LocalDateTime{})
|
||||||
|
var mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
|
||||||
|
|
||||||
// Check if the given marshal type maps to a Tree primitive
|
// Check if the given marshal type maps to a Tree primitive
|
||||||
func isPrimitive(mtype reflect.Type) bool {
|
func isPrimitive(mtype reflect.Type) bool {
|
||||||
@@ -703,6 +704,8 @@ func (d *Decoder) unmarshal(v interface{}) error {
|
|||||||
|
|
||||||
switch elem.Kind() {
|
switch elem.Kind() {
|
||||||
case reflect.Struct, reflect.Map:
|
case reflect.Struct, reflect.Map:
|
||||||
|
case reflect.Interface:
|
||||||
|
elem = mapStringInterfaceType
|
||||||
default:
|
default:
|
||||||
return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
|
return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3888,3 +3888,56 @@ func TestPreserveNotEmptyField(t *testing.T) {
|
|||||||
t.Errorf("Bad unmarshal: expected %+v, got %+v", expected, actual)
|
t.Errorf("Bad unmarshal: expected %+v, got %+v", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// github issue 432
|
||||||
|
func TestUnmarshalEmptyInterface(t *testing.T) {
|
||||||
|
doc := []byte(`User = "pelletier"`)
|
||||||
|
|
||||||
|
var v interface{}
|
||||||
|
|
||||||
|
err := Unmarshal(doc, &v)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
x, ok := v.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if x["User"] != "pelletier" {
|
||||||
|
t.Fatalf("expected User=pelletier, but got %v", x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalEmptyInterfaceDeep(t *testing.T) {
|
||||||
|
doc := []byte(`
|
||||||
|
User = "pelletier"
|
||||||
|
Age = 99
|
||||||
|
|
||||||
|
[foo]
|
||||||
|
bar = 42
|
||||||
|
`)
|
||||||
|
|
||||||
|
var v interface{}
|
||||||
|
|
||||||
|
err := Unmarshal(doc, &v)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
x, ok := v.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := map[string]interface{}{
|
||||||
|
"User": "pelletier",
|
||||||
|
"Age": 99,
|
||||||
|
"foo": map[string]interface{}{
|
||||||
|
"bar": 42,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
reflect.DeepEqual(x, expected)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user