Target set methods now check for types
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user