Target set methods now check for types

This commit is contained in:
Thomas Pelletier
2021-02-19 08:39:18 -05:00
parent 052233e858
commit 7f9822db35
2 changed files with 46 additions and 46 deletions
@@ -421,26 +421,6 @@ func TestErrUnmarshal(t *testing.T) {
} }
} }
type emptyMarshalTestStruct struct {
Title string `toml:"title"`
Bool bool `toml:"bool"`
Int int `toml:"int"`
String string `toml:"string"`
StringList []string `toml:"stringlist"`
Ptr *basicMarshalTestStruct `toml:"ptr"`
Map map[string]string `toml:"map"`
}
var emptyTestData = emptyMarshalTestStruct{
Title: "Placeholder",
Bool: false,
Int: 0,
String: "",
StringList: []string{},
Ptr: nil,
Map: map[string]string{},
}
var emptyTestToml = []byte(`bool = false var emptyTestToml = []byte(`bool = false
int = 0 int = 0
string = "" string = ""
@@ -474,15 +454,30 @@ var emptyTestToml2 = []byte(`title = "Placeholder"
`) `)
func TestEmptytomlUnmarshal(t *testing.T) { func TestEmptytomlUnmarshal(t *testing.T) {
type emptyMarshalTestStruct struct {
Title string `toml:"title"`
Bool bool `toml:"bool"`
Int int `toml:"int"`
String string `toml:"string"`
StringList []string `toml:"stringlist"`
Ptr *basicMarshalTestStruct `toml:"ptr"`
Map map[string]string `toml:"map"`
}
emptyTestData := emptyMarshalTestStruct{
Title: "Placeholder",
Bool: false,
Int: 0,
String: "",
StringList: []string{},
Ptr: nil,
Map: map[string]string{},
}
result := emptyMarshalTestStruct{} result := emptyMarshalTestStruct{}
err := toml.Unmarshal(emptyTestToml, &result) err := toml.Unmarshal(emptyTestToml, &result)
expected := emptyTestData require.NoError(t, err)
if err != nil { assert.Equal(t, emptyTestData, result)
t.Fatal(err)
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("Bad empty unmarshal: expected %v, got %v", expected, result)
}
} }
func TestEmptyUnmarshalOmit(t *testing.T) { func TestEmptyUnmarshalOmit(t *testing.T) {
+24 -19
View File
@@ -17,19 +17,32 @@ type structFieldGetters map[string]fieldGetter
type target interface { type target interface {
get() reflect.Value get() reflect.Value
set(value reflect.Value) set(value reflect.Value) error
fmt.Stringer fmt.Stringer
} }
func isAssignable(t reflect.Type, v reflect.Value) error {
if v.Type().AssignableTo(t) {
return nil
}
return fmt.Errorf("cannot assign '%s' ('%s') to a '%s'", v, v.Type(), t)
}
type valueTarget reflect.Value type valueTarget reflect.Value
func (v valueTarget) get() reflect.Value { func (v valueTarget) get() reflect.Value {
return reflect.Value(v) return reflect.Value(v)
} }
func (v valueTarget) set(value reflect.Value) { func (v valueTarget) set(value reflect.Value) error {
rv := reflect.Value(v)
err := isAssignable(rv.Type(), value)
if err != nil {
return err
}
reflect.Value(v).Set(value) reflect.Value(v).Set(value)
return nil
} }
func (v valueTarget) String() string { func (v valueTarget) String() string {
@@ -45,8 +58,13 @@ func (v mapTarget) get() reflect.Value {
return v.m.MapIndex(v.index) return v.m.MapIndex(v.index)
} }
func (v mapTarget) set(value reflect.Value) { func (v mapTarget) set(value reflect.Value) error {
err := isAssignable(v.m.Type().Elem(), value)
if err != nil {
return err
}
v.m.SetMapIndex(v.index, value) v.m.SetMapIndex(v.index, value)
return nil
} }
func (v mapTarget) String() string { func (v mapTarget) String() string {
@@ -413,23 +431,11 @@ func (b *Builder) SetString(s string) error {
t := b.top() t := b.top()
v := t.get() v := t.get()
if !v.IsValid() {
fmt.Println("============ INVALID ===========")
fmt.Println(b.Dump())
fmt.Println("==================== ===========")
}
if v.Kind() == reflect.Ptr { if v.Kind() == reflect.Ptr {
v.Set(reflect.ValueOf(&s)) v.Set(reflect.ValueOf(&s))
} else { return nil
err := checkKind(v.Type(), reflect.String)
if err != nil {
return err
}
v.SetString(s)
} }
return nil return t.set(reflect.ValueOf(s))
} }
// Set the value at the cursor to the given boolean. // Set the value at the cursor to the given boolean.
@@ -481,8 +487,7 @@ func (b *Builder) SetInt(n int64) error {
func (b *Builder) Set(v reflect.Value) error { func (b *Builder) Set(v reflect.Value) error {
t := b.top() t := b.top()
t.set(v) return t.set(v)
return nil
} }
func checkKindInt(rt reflect.Type) error { func checkKindInt(rt reflect.Type) error {