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:
Thomas Pelletier
2020-09-11 10:04:46 -04:00
committed by GitHub
parent 196ce3a1f6
commit b76eb62117
2 changed files with 56 additions and 0 deletions
+3
View File
@@ -76,6 +76,7 @@ var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
var localDateType = reflect.TypeOf(LocalDate{})
var localTimeType = reflect.TypeOf(LocalTime{})
var localDateTimeType = reflect.TypeOf(LocalDateTime{})
var mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
// Check if the given marshal type maps to a Tree primitive
func isPrimitive(mtype reflect.Type) bool {
@@ -703,6 +704,8 @@ func (d *Decoder) unmarshal(v interface{}) error {
switch elem.Kind() {
case reflect.Struct, reflect.Map:
case reflect.Interface:
elem = mapStringInterfaceType
default:
return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
}
+53
View File
@@ -3888,3 +3888,56 @@ func TestPreserveNotEmptyField(t *testing.T) {
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)
}