Handle pointers in slices
This commit is contained in:
@@ -517,7 +517,6 @@ Str = "Hello"
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
func TestPointerUnmarshal(t *testing.T) {
|
func TestPointerUnmarshal(t *testing.T) {
|
||||||
t.Log("TOML data:", string(pointerTestToml))
|
|
||||||
result := pointerMarshalTestStruct{}
|
result := pointerMarshalTestStruct{}
|
||||||
err := toml.Unmarshal(pointerTestToml, &result)
|
err := toml.Unmarshal(pointerTestToml, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
+15
-1
@@ -129,17 +129,29 @@ func ensureSlice(t target) error {
|
|||||||
}
|
}
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
if f.IsNil() {
|
if f.IsNil() {
|
||||||
return t.set(reflect.MakeSlice(reflect.TypeOf([]interface{}{}), 0, 0))
|
return t.set(reflect.MakeSlice(sliceInterfaceType, 0, 0))
|
||||||
}
|
}
|
||||||
if f.Type().Elem().Kind() != reflect.Slice {
|
if f.Type().Elem().Kind() != reflect.Slice {
|
||||||
return fmt.Errorf("interface is pointing to a %s, not a slice", f.Kind())
|
return fmt.Errorf("interface is pointing to a %s, not a slice", f.Kind())
|
||||||
}
|
}
|
||||||
|
case reflect.Ptr:
|
||||||
|
if f.IsNil() {
|
||||||
|
ptr := reflect.New(f.Type().Elem())
|
||||||
|
err := t.set(ptr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f = t.get()
|
||||||
|
}
|
||||||
|
return ensureSlice(valueTarget(f.Elem()))
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("cannot initialize a slice in %s", f.Kind())
|
return fmt.Errorf("cannot initialize a slice in %s", f.Kind())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sliceInterfaceType = reflect.TypeOf([]interface{}{})
|
||||||
|
|
||||||
func setString(t target, v string) error {
|
func setString(t target, v string) error {
|
||||||
f := t.get()
|
f := t.get()
|
||||||
|
|
||||||
@@ -261,6 +273,8 @@ func pushNew(t target) (target, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return valueTarget(t.get().Elem().Index(idx)), nil
|
return valueTarget(t.get().Elem().Index(idx)), nil
|
||||||
|
case reflect.Ptr:
|
||||||
|
return pushNew(valueTarget(f.Elem()))
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("cannot pushNew on a %s", f.Kind())
|
return nil, fmt.Errorf("cannot pushNew on a %s", f.Kind())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,6 +572,22 @@ B = "data"`,
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "slice pointer in slice pointer",
|
||||||
|
input: `A = ["Hello"]`,
|
||||||
|
gen: func() test {
|
||||||
|
type doc struct {
|
||||||
|
A *[]*string
|
||||||
|
}
|
||||||
|
hello := "Hello"
|
||||||
|
return test{
|
||||||
|
target: &doc{},
|
||||||
|
expected: &doc{
|
||||||
|
A: &[]*string{&hello},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range examples {
|
for _, e := range examples {
|
||||||
|
|||||||
Reference in New Issue
Block a user