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] Unmarshal into maps.
- [x] Support Array Tables. - [x] Support Array Tables.
- [ ] Unmarshal into pointers. - [x] Unmarshal into pointers.
- [ ] Support Date / times. - [ ] Support Date / times.
- [ ] Support Unmarshaler interface. - [ ] Support Unmarshaler interface.
- [ ] Support struct tags annotations. - [ ] Support struct tags annotations.
@@ -138,13 +138,8 @@ func TestInterface(t *testing.T) {
func TestBasicUnmarshal(t *testing.T) { func TestBasicUnmarshal(t *testing.T) {
result := basicMarshalTestStruct{} result := basicMarshalTestStruct{}
err := toml.Unmarshal(basicTestToml, &result) err := toml.Unmarshal(basicTestToml, &result)
expected := basicTestData require.NoError(t, err)
if err != nil { require.Equal(t, basicTestData, result)
t.Fatal(err)
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("Bad unmarshal: expected %v, got %v", expected, result)
}
} }
type quotedKeyMarshalTestStruct struct { type quotedKeyMarshalTestStruct struct {
+31 -4
View File
@@ -229,16 +229,20 @@ func scopeTableTarget(append bool, t target, name string) (target, error) {
x := t.get() x := t.get()
switch x.Kind() { switch x.Kind() {
// Kinds that need to recurse
case reflect.Interface: case reflect.Interface:
t, err := scopeInterface(append, t) t, err := scopeInterface(append, t)
if err != nil { if err != nil {
return t, err return t, err
} }
return scopeTableTarget(append, t, name) return scopeTableTarget(append, t, name)
case reflect.Struct: case reflect.Ptr:
return scopeStruct(x, name) t, err := scopePtr(t)
case reflect.Map: if err != nil {
return scopeMap(x, name) return t, err
}
return scopeTableTarget(append, t, name)
case reflect.Slice: case reflect.Slice:
t, err := scopeSlice(append, t) t, err := scopeSlice(append, t)
if err != nil { if err != nil {
@@ -246,6 +250,13 @@ func scopeTableTarget(append bool, t target, name string) (target, error) {
} }
append = false append = false
return scopeTableTarget(append, t, name) return scopeTableTarget(append, t, name)
// Terminal kinds
case reflect.Struct:
return scopeStruct(x, name)
case reflect.Map:
return scopeMap(x, name)
default: default:
panic(fmt.Errorf("can't scope on a %s", x.Kind())) 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 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 // initInterface makes sure that the interface pointed at by the target is not
// nil. // nil.
// Returns the target to the initialized value of the target. // Returns the target to the initialized value of the target.