Handle interface field dereference
This commit is contained in:
@@ -17,6 +17,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pelletier/go-toml/v2"
|
"github.com/pelletier/go-toml/v2"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
type basicMarshalTestStruct struct {
|
type basicMarshalTestStruct struct {
|
||||||
@@ -57,34 +59,6 @@ Zstring = "Hello"
|
|||||||
String2 = "Two"
|
String2 = "Two"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
var basicTestTomlCustomIndentation = []byte(`String3 = "One"
|
|
||||||
Ystrlist = ["Howdy", "Hey There"]
|
|
||||||
Zstring = "Hello"
|
|
||||||
|
|
||||||
[[Wsublist]]
|
|
||||||
String2 = "Three"
|
|
||||||
|
|
||||||
[[Wsublist]]
|
|
||||||
String2 = "Four"
|
|
||||||
|
|
||||||
[Xsubdoc]
|
|
||||||
String2 = "Two"
|
|
||||||
`)
|
|
||||||
|
|
||||||
var basicTestTomlOrdered = []byte(`Zstring = "Hello"
|
|
||||||
Ystrlist = ["Howdy", "Hey There"]
|
|
||||||
String3 = "One"
|
|
||||||
|
|
||||||
[Xsubdoc]
|
|
||||||
String2 = "Two"
|
|
||||||
|
|
||||||
[[Wsublist]]
|
|
||||||
String2 = "Three"
|
|
||||||
|
|
||||||
[[Wsublist]]
|
|
||||||
String2 = "Four"
|
|
||||||
`)
|
|
||||||
|
|
||||||
var marshalTestToml = []byte(`title = "TOML Marshal Testing"
|
var marshalTestToml = []byte(`title = "TOML Marshal Testing"
|
||||||
|
|
||||||
[basic]
|
[basic]
|
||||||
@@ -126,66 +100,6 @@ var marshalTestToml = []byte(`title = "TOML Marshal Testing"
|
|||||||
name = "Second"
|
name = "Second"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
var marshalOrderPreserveToml = []byte(`title = "TOML Marshal Testing"
|
|
||||||
|
|
||||||
[basic_lists]
|
|
||||||
floats = [12.3, 45.6, 78.9]
|
|
||||||
bools = [true, false, true]
|
|
||||||
dates = [1979-05-27T07:32:00Z, 1980-05-27T07:32:00Z]
|
|
||||||
ints = [8001, 8001, 8002]
|
|
||||||
uints = [5002, 5003]
|
|
||||||
strings = ["One", "Two", "Three"]
|
|
||||||
|
|
||||||
[[subdocptrs]]
|
|
||||||
name = "Second"
|
|
||||||
|
|
||||||
[basic_map]
|
|
||||||
one = "one"
|
|
||||||
two = "two"
|
|
||||||
|
|
||||||
[subdoc]
|
|
||||||
|
|
||||||
[subdoc.second]
|
|
||||||
name = "Second"
|
|
||||||
|
|
||||||
[subdoc.first]
|
|
||||||
name = "First"
|
|
||||||
|
|
||||||
[basic]
|
|
||||||
uint = 5001
|
|
||||||
bool = true
|
|
||||||
float = 123.4
|
|
||||||
float64 = 123.456782132399
|
|
||||||
int = 5000
|
|
||||||
string = "Bite me"
|
|
||||||
date = 1979-05-27T07:32:00Z
|
|
||||||
|
|
||||||
[[subdoclist]]
|
|
||||||
name = "List.First"
|
|
||||||
|
|
||||||
[[subdoclist]]
|
|
||||||
name = "List.Second"
|
|
||||||
`)
|
|
||||||
|
|
||||||
var mashalOrderPreserveMapToml = []byte(`title = "TOML Marshal Testing"
|
|
||||||
|
|
||||||
[basic_map]
|
|
||||||
one = "one"
|
|
||||||
two = "two"
|
|
||||||
|
|
||||||
[long_map]
|
|
||||||
a7 = "1"
|
|
||||||
b3 = "2"
|
|
||||||
c8 = "3"
|
|
||||||
d4 = "4"
|
|
||||||
e6 = "5"
|
|
||||||
f5 = "6"
|
|
||||||
g10 = "7"
|
|
||||||
h1 = "8"
|
|
||||||
i2 = "9"
|
|
||||||
j9 = "10"
|
|
||||||
`)
|
|
||||||
|
|
||||||
type Conf struct {
|
type Conf struct {
|
||||||
Name string
|
Name string
|
||||||
Age int
|
Age int
|
||||||
@@ -210,6 +124,7 @@ func TestInterface(t *testing.T) {
|
|||||||
var config Conf
|
var config Conf
|
||||||
config.Inter = &NestedStruct{}
|
config.Inter = &NestedStruct{}
|
||||||
err := toml.Unmarshal(doc, &config)
|
err := toml.Unmarshal(doc, &config)
|
||||||
|
require.NoError(t, err)
|
||||||
expected := Conf{
|
expected := Conf{
|
||||||
Name: "rui",
|
Name: "rui",
|
||||||
Age: 18,
|
Age: 18,
|
||||||
@@ -219,9 +134,7 @@ func TestInterface(t *testing.T) {
|
|||||||
Age: 100,
|
Age: 100,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err != nil || !reflect.DeepEqual(config, expected) {
|
assert.Equal(t, expected, config)
|
||||||
t.Errorf("Bad unmarshal: expected %v, got %v", expected, config)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicUnmarshal(t *testing.T) {
|
func TestBasicUnmarshal(t *testing.T) {
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ func (b *Builder) top() reflect.Value {
|
|||||||
|
|
||||||
func (b *Builder) push(v reflect.Value) {
|
func (b *Builder) push(v reflect.Value) {
|
||||||
b.stack = append(b.stack, v)
|
b.stack = append(b.stack, v)
|
||||||
|
// TODO: remove me. just here to make sure the method is included in the
|
||||||
|
// binary for debug
|
||||||
|
b.Dump()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) pop() {
|
func (b *Builder) pop() {
|
||||||
@@ -73,10 +76,15 @@ func (b *Builder) replace(v reflect.Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DigField pushes the cursor into a field of the current struct.
|
// DigField pushes the cursor into a field of the current struct.
|
||||||
|
// Dereferences all pointers found along the way.
|
||||||
// Errors if the current value is not a struct, or the field does not exist.
|
// Errors if the current value is not a struct, or the field does not exist.
|
||||||
func (b *Builder) DigField(s string) error {
|
func (b *Builder) DigField(s string) error {
|
||||||
t := b.top()
|
t := b.top()
|
||||||
|
|
||||||
|
for t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
err := checkKind(t.Type(), reflect.Struct)
|
err := checkKind(t.Type(), reflect.Struct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -615,7 +615,11 @@ func (p parser) parseIntOrFloatOrDateTime(b []byte) ([]byte, error) {
|
|||||||
if len(b) < 3 {
|
if len(b) < 3 {
|
||||||
return p.parseIntOrFloat(b)
|
return p.parseIntOrFloat(b)
|
||||||
}
|
}
|
||||||
for idx, c := range b[:5] {
|
s := 5
|
||||||
|
if len(b) < s {
|
||||||
|
s = len(b)
|
||||||
|
}
|
||||||
|
for idx, c := range b[:s] {
|
||||||
if c >= '0' && c <= '9' {
|
if c >= '0' && c <= '9' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user