wip: debugging maps
This commit is contained in:
@@ -298,12 +298,6 @@ func TestDocUnmarshal(t *testing.T) {
|
|||||||
assert.Equal(t, expected, result)
|
assert.Equal(t, expected, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
type tomlTypeCheckTest struct {
|
|
||||||
name string
|
|
||||||
item interface{}
|
|
||||||
typ int //0=primitive, 1=otherslice, 2=treeslice, 3=tree
|
|
||||||
}
|
|
||||||
|
|
||||||
type unexportedMarshalTestStruct struct {
|
type unexportedMarshalTestStruct struct {
|
||||||
String string `toml:"string"`
|
String string `toml:"string"`
|
||||||
StringList []string `toml:"strlist"`
|
StringList []string `toml:"strlist"`
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ 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)
|
||||||
|
|
||||||
|
fmt.Stringer
|
||||||
}
|
}
|
||||||
|
|
||||||
type valueTarget reflect.Value
|
type valueTarget reflect.Value
|
||||||
@@ -30,6 +32,10 @@ func (v valueTarget) set(value reflect.Value) {
|
|||||||
reflect.Value(v).Set(value)
|
reflect.Value(v).Set(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v valueTarget) String() string {
|
||||||
|
return fmt.Sprintf("valueTarget: '%s' (%s)", reflect.Value(v), reflect.Value(v).Type())
|
||||||
|
}
|
||||||
|
|
||||||
type mapTarget struct {
|
type mapTarget struct {
|
||||||
index reflect.Value
|
index reflect.Value
|
||||||
m reflect.Value
|
m reflect.Value
|
||||||
@@ -43,6 +49,10 @@ func (v mapTarget) set(value reflect.Value) {
|
|||||||
v.m.SetMapIndex(v.index, value)
|
v.m.SetMapIndex(v.index, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v mapTarget) String() string {
|
||||||
|
return fmt.Sprintf("mapTarget: '%s'[%s]", v.m, v.index)
|
||||||
|
}
|
||||||
|
|
||||||
// Builder wraps a value and provides method to modify its structure.
|
// Builder wraps a value and provides method to modify its structure.
|
||||||
// It is a stateful object that keeps a cursor of what part of the object is
|
// It is a stateful object that keeps a cursor of what part of the object is
|
||||||
// being modified.
|
// being modified.
|
||||||
@@ -151,7 +161,9 @@ func NewBuilder(tag string, v interface{}) (Builder, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) top() target {
|
func (b *Builder) top() target {
|
||||||
return b.stack[len(b.stack)-1]
|
t := b.stack[len(b.stack)-1]
|
||||||
|
fmt.Println("TOP:", t)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) duplicate() {
|
func (b *Builder) duplicate() {
|
||||||
@@ -163,6 +175,7 @@ func (b *Builder) duplicate() {
|
|||||||
|
|
||||||
func (b *Builder) pop() {
|
func (b *Builder) pop() {
|
||||||
b.stack = b.stack[:len(b.stack)-1]
|
b.stack = b.stack[:len(b.stack)-1]
|
||||||
|
fmt.Println("POP: top:", b.stack[len(b.stack)-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) len() int {
|
func (b *Builder) len() int {
|
||||||
@@ -185,6 +198,7 @@ func (b *Builder) Dump() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) replace(v target) {
|
func (b *Builder) replace(v target) {
|
||||||
|
fmt.Println("REPLACING:", v)
|
||||||
b.stack[len(b.stack)-1] = v
|
b.stack[len(b.stack)-1] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,18 +371,54 @@ func (b *Builder) SliceAppend(value reflect.Value) error {
|
|||||||
value = value.Elem()
|
value = value.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.Type().Elem() != value.Type() {
|
||||||
|
nv, err := tryConvert(v.Type().Elem(), value)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot assign '%s' to '%s'", value.Type(), v.Type().Elem())
|
||||||
|
}
|
||||||
|
value = nv
|
||||||
|
}
|
||||||
|
|
||||||
newSlice := reflect.Append(v, value)
|
newSlice := reflect.Append(v, value)
|
||||||
v.Set(newSlice)
|
v.Set(newSlice)
|
||||||
b.replace(valueTarget(v.Index(v.Len() - 1))) // TODO: "sliceTarget" ?
|
b.replace(valueTarget(v.Index(v.Len() - 1))) // TODO: "sliceTarget" ?
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tryConvert(t reflect.Type, value reflect.Value) (reflect.Value, error) {
|
||||||
|
result := value
|
||||||
|
if value.Kind() == reflect.Ptr {
|
||||||
|
if t.Kind() != reflect.Ptr {
|
||||||
|
return reflect.Value{}, fmt.Errorf("cannot convert pointer to non-pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.Type().Elem().ConvertibleTo(t.Elem()) {
|
||||||
|
result = reflect.New(t.Elem())
|
||||||
|
result.Elem().Set(value.Elem().Convert(t.Elem()))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if value.Type().ConvertibleTo(t) {
|
||||||
|
result = reflect.New(t)
|
||||||
|
result.Elem().Set(value.Convert(t))
|
||||||
|
return result.Elem(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, fmt.Errorf("no conversion found")
|
||||||
|
}
|
||||||
|
|
||||||
// Set the value at the cursor to the given string.
|
// Set the value at the cursor to the given string.
|
||||||
// Errors if a string cannot be assigned to the current value.
|
// Errors if a string cannot be assigned to the current value.
|
||||||
func (b *Builder) SetString(s string) error {
|
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 {
|
} else {
|
||||||
@@ -416,8 +466,14 @@ func (b *Builder) SetInt(n int64) error {
|
|||||||
|
|
||||||
err := checkKindInt(v.Type())
|
err := checkKindInt(v.Type())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
rn := reflect.ValueOf(n)
|
||||||
|
if rn.Type().ConvertibleTo(v.Type()) {
|
||||||
|
v.Set(rn.Convert(v.Type()))
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v.SetInt(n)
|
v.SetInt(n)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user