Unmarshal into pointers

This commit is contained in:
Thomas Pelletier
2021-03-18 20:02:32 -04:00
parent 8957a768ef
commit 3e8b8db786
3 changed files with 34 additions and 12 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ Development branch. Probably does not work.
- [x] Unmarshal into maps.
- [x] Support Array Tables.
- [ ] Unmarshal into pointers.
- [x] Unmarshal into pointers.
- [ ] Support Date / times.
- [ ] Support Unmarshaler interface.
- [ ] Support struct tags annotations.
@@ -138,13 +138,8 @@ func TestInterface(t *testing.T) {
func TestBasicUnmarshal(t *testing.T) {
result := basicMarshalTestStruct{}
err := toml.Unmarshal(basicTestToml, &result)
expected := basicTestData
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("Bad unmarshal: expected %v, got %v", expected, result)
}
require.NoError(t, err)
require.Equal(t, basicTestData, result)
}
type quotedKeyMarshalTestStruct struct {
+31 -4
View File
@@ -229,16 +229,20 @@ func scopeTableTarget(append bool, t target, name string) (target, error) {
x := t.get()
switch x.Kind() {
// Kinds that need to recurse
case reflect.Interface:
t, err := scopeInterface(append, t)
if err != nil {
return t, err
}
return scopeTableTarget(append, t, name)
case reflect.Struct:
return scopeStruct(x, name)
case reflect.Map:
return scopeMap(x, name)
case reflect.Ptr:
t, err := scopePtr(t)
if err != nil {
return t, err
}
return scopeTableTarget(append, t, name)
case reflect.Slice:
t, err := scopeSlice(append, t)
if err != nil {
@@ -246,6 +250,13 @@ func scopeTableTarget(append bool, t target, name string) (target, error) {
}
append = false
return scopeTableTarget(append, t, name)
// Terminal kinds
case reflect.Struct:
return scopeStruct(x, name)
case reflect.Map:
return scopeMap(x, name)
default:
panic(fmt.Errorf("can't scope on a %s", x.Kind()))
}
@@ -260,6 +271,22 @@ func scopeInterface(append bool, t target) (target, error) {
return interfaceTarget{t}, nil
}
func scopePtr(t target) (target, error) {
err := initPtr(t)
if err != nil {
return t, err
}
return valueTarget(t.get().Elem()), nil
}
func initPtr(t target) error {
x := t.get()
if !x.IsNil() {
return nil
}
return t.set(reflect.New(x.Type().Elem()))
}
// initInterface makes sure that the interface pointed at by the target is not
// nil.
// Returns the target to the initialized value of the target.