Skip to content

Commit b76eb62

Browse files
authored
Marshal into empty interface{} (#433)
Allows to marshal a TOML document into an empty `interface{}`, resulting in a `map[string]interface{}`. Fixes #432
1 parent 196ce3a commit b76eb62

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

marshal.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
7676
var localDateType = reflect.TypeOf(LocalDate{})
7777
var localTimeType = reflect.TypeOf(LocalTime{})
7878
var localDateTimeType = reflect.TypeOf(LocalDateTime{})
79+
var mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
7980

8081
// Check if the given marshal type maps to a Tree primitive
8182
func isPrimitive(mtype reflect.Type) bool {
@@ -703,6 +704,8 @@ func (d *Decoder) unmarshal(v interface{}) error {
703704

704705
switch elem.Kind() {
705706
case reflect.Struct, reflect.Map:
707+
case reflect.Interface:
708+
elem = mapStringInterfaceType
706709
default:
707710
return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
708711
}

marshal_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3888,3 +3888,56 @@ func TestPreserveNotEmptyField(t *testing.T) {
38883888
t.Errorf("Bad unmarshal: expected %+v, got %+v", expected, actual)
38893889
}
38903890
}
3891+
3892+
// github issue 432
3893+
func TestUnmarshalEmptyInterface(t *testing.T) {
3894+
doc := []byte(`User = "pelletier"`)
3895+
3896+
var v interface{}
3897+
3898+
err := Unmarshal(doc, &v)
3899+
if err != nil {
3900+
t.Fatal(err)
3901+
}
3902+
3903+
x, ok := v.(map[string]interface{})
3904+
if !ok {
3905+
t.Fatal(err)
3906+
}
3907+
3908+
if x["User"] != "pelletier" {
3909+
t.Fatalf("expected User=pelletier, but got %v", x)
3910+
}
3911+
}
3912+
3913+
func TestUnmarshalEmptyInterfaceDeep(t *testing.T) {
3914+
doc := []byte(`
3915+
User = "pelletier"
3916+
Age = 99
3917+
3918+
[foo]
3919+
bar = 42
3920+
`)
3921+
3922+
var v interface{}
3923+
3924+
err := Unmarshal(doc, &v)
3925+
if err != nil {
3926+
t.Fatal(err)
3927+
}
3928+
3929+
x, ok := v.(map[string]interface{})
3930+
if !ok {
3931+
t.Fatal(err)
3932+
}
3933+
3934+
expected := map[string]interface{}{
3935+
"User": "pelletier",
3936+
"Age": 99,
3937+
"foo": map[string]interface{}{
3938+
"bar": 42,
3939+
},
3940+
}
3941+
3942+
reflect.DeepEqual(x, expected)
3943+
}

0 commit comments

Comments
 (0)