v2: errors (#534)
``` name old time/op new time/op delta UnmarshalDataset/config-32 86.7ms ± 2% 87.5ms ± 2% ~ (p=0.113 n=9+10) UnmarshalDataset/canada-32 129ms ± 4% 106ms ± 3% -17.94% (p=0.000 n=10+10) UnmarshalDataset/citm_catalog-32 59.4ms ± 5% 58.7ms ± 5% ~ (p=0.393 n=10+10) UnmarshalDataset/twitter-32 27.0ms ± 7% 26.9ms ± 6% ~ (p=0.720 n=10+9) UnmarshalDataset/code-32 326ms ± 4% 322ms ± 7% ~ (p=0.661 n=9+10) UnmarshalDataset/example-32 510µs ±11% 526µs ± 7% ~ (p=0.182 n=10+9) UnmarshalSimple-32 1.41µs ± 6% 1.41µs ± 4% ~ (p=0.736 n=10+9) ReferenceFile-32 45.6µs ± 3% 43.9µs ±10% ~ (p=0.089 n=10+10) name old speed new speed delta UnmarshalDataset/config-32 12.1MB/s ± 2% 12.0MB/s ± 2% ~ (p=0.108 n=9+10) UnmarshalDataset/canada-32 17.1MB/s ± 4% 20.9MB/s ± 3% +21.86% (p=0.000 n=10+10) UnmarshalDataset/citm_catalog-32 9.41MB/s ± 5% 9.51MB/s ± 5% ~ (p=0.362 n=10+10) UnmarshalDataset/twitter-32 16.4MB/s ± 8% 16.5MB/s ± 6% ~ (p=0.704 n=10+9) UnmarshalDataset/code-32 8.24MB/s ± 4% 8.34MB/s ± 7% ~ (p=0.675 n=9+10) UnmarshalDataset/example-32 15.9MB/s ±11% 15.4MB/s ± 7% ~ (p=0.182 n=10+9) ReferenceFile-32 115MB/s ± 4% 120MB/s ±10% ~ (p=0.085 n=10+10) name old alloc/op new alloc/op delta UnmarshalDataset/config-32 16.9MB ± 0% 16.9MB ± 0% -0.02% (p=0.000 n=10+10) UnmarshalDataset/canada-32 76.8MB ± 0% 74.3MB ± 0% -3.31% (p=0.000 n=10+10) UnmarshalDataset/citm_catalog-32 37.3MB ± 0% 37.1MB ± 0% -0.60% (p=0.000 n=9+10) UnmarshalDataset/twitter-32 15.6MB ± 0% 15.6MB ± 0% -0.09% (p=0.000 n=10+10) UnmarshalDataset/code-32 60.2MB ± 0% 59.3MB ± 0% -1.51% (p=0.000 n=10+9) UnmarshalDataset/example-32 238kB ± 0% 238kB ± 0% -0.18% (p=0.000 n=10+10) ReferenceFile-32 11.8kB ± 0% 11.8kB ± 0% ~ (all equal) name old allocs/op new allocs/op delta UnmarshalDataset/config-32 653k ± 0% 645k ± 0% -1.20% (p=0.000 n=10+6) UnmarshalDataset/canada-32 1.01M ± 0% 0.90M ± 0% -11.04% (p=0.000 n=9+10) UnmarshalDataset/citm_catalog-32 384k ± 0% 370k ± 0% -3.75% (p=0.000 n=10+10) UnmarshalDataset/twitter-32 160k ± 0% 157k ± 0% -1.32% (p=0.000 n=10+10) UnmarshalDataset/code-32 2.97M ± 0% 2.91M ± 0% -2.15% (p=0.000 n=10+7) UnmarshalDataset/example-32 3.69k ± 0% 3.63k ± 0% -1.52% (p=0.000 n=10+10) ReferenceFile-32 253 ± 0% 253 ± 0% ~ (all equal) ```
This commit is contained in:
+34
-67
@@ -56,7 +56,7 @@ func (d *Decoder) SetStrict(strict bool) {
|
||||
func (d *Decoder) Decode(v interface{}) error {
|
||||
b, err := ioutil.ReadAll(d.r)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Decode: %w", err)
|
||||
return fmt.Errorf("toml: %w", err)
|
||||
}
|
||||
|
||||
p := parser{}
|
||||
@@ -130,20 +130,15 @@ func keyLocation(node ast.Node) []byte {
|
||||
return unsafe.BytesRange(start, end)
|
||||
}
|
||||
|
||||
var (
|
||||
errFromParserExpectingPointer = errors.New("expecting a pointer as target")
|
||||
errFromParserExpectingNonNilPointer = errors.New("expecting non nil pointer as target")
|
||||
)
|
||||
|
||||
//nolint:funlen,cyclop
|
||||
func (d *decoder) fromParser(p *parser, v interface{}) error {
|
||||
r := reflect.ValueOf(v)
|
||||
if r.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("fromParser: %w, not %s", errFromParserExpectingPointer, r.Kind())
|
||||
return fmt.Errorf("toml: decoding can only be performed into a pointer, not %s", r.Kind())
|
||||
}
|
||||
|
||||
if r.IsNil() {
|
||||
return errFromParserExpectingNonNilPointer
|
||||
return fmt.Errorf("toml: decoding pointer target cannot be nil")
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -162,7 +157,7 @@ func (d *decoder) fromParser(p *parser, v interface{}) error {
|
||||
|
||||
err := d.seen.CheckExpression(node)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fromParser: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
var found bool
|
||||
@@ -181,16 +176,13 @@ func (d *decoder) fromParser(p *parser, v interface{}) error {
|
||||
// looks like a table. Otherwise the information
|
||||
// of a table is lost, and marshal cannot do the
|
||||
// round trip.
|
||||
err := ensureMapIfInterface(current)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("ensureMapIfInterface: %s", err))
|
||||
}
|
||||
ensureMapIfInterface(current)
|
||||
}
|
||||
case ast.ArrayTable:
|
||||
d.strict.EnterArrayTable(node)
|
||||
current, found, err = d.scopeWithArrayTable(root, node.Key())
|
||||
default:
|
||||
panic(fmt.Sprintf("fromParser: this should not be a top level node type: %s", node.Kind))
|
||||
panic(fmt.Sprintf("this should not be a top level node type: %s", node.Kind))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -267,26 +259,18 @@ func (d *decoder) scopeWithArrayTable(x target, key ast.Iterator) (target, bool,
|
||||
v := x.get()
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
x, err = scopePtr(x)
|
||||
if err != nil {
|
||||
return x, false, err
|
||||
}
|
||||
|
||||
x = scopePtr(x)
|
||||
v = x.get()
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.Interface {
|
||||
x, err = scopeInterface(true, x)
|
||||
if err != nil {
|
||||
return x, found, err
|
||||
}
|
||||
|
||||
x = scopeInterface(true, x)
|
||||
v = x.get()
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Slice:
|
||||
x, err = scopeSlice(true, x)
|
||||
x = scopeSlice(true, x)
|
||||
case reflect.Array:
|
||||
x, err = d.scopeArray(true, x)
|
||||
default:
|
||||
@@ -334,7 +318,7 @@ func tryTextUnmarshaler(x target, node ast.Node) (bool, error) {
|
||||
if v.Type().Implements(textUnmarshalerType) {
|
||||
err := v.Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("tryTextUnmarshaler: %w", err)
|
||||
return false, newDecodeError(node.Data, "error calling UnmarshalText: %w", err)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
@@ -343,7 +327,7 @@ func tryTextUnmarshaler(x target, node ast.Node) (bool, error) {
|
||||
if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) {
|
||||
err := v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("tryTextUnmarshaler: %w", err)
|
||||
return false, newDecodeError(node.Data, "error calling UnmarshalText: %w", err)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
@@ -358,11 +342,7 @@ func (d *decoder) unmarshalValue(x target, node ast.Node) error {
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if !v.Elem().IsValid() {
|
||||
err := x.set(reflect.New(v.Type().Elem()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshalValue: %w", err)
|
||||
}
|
||||
|
||||
x.set(reflect.New(v.Type().Elem()))
|
||||
v = x.get()
|
||||
}
|
||||
|
||||
@@ -394,7 +374,7 @@ func (d *decoder) unmarshalValue(x target, node ast.Node) error {
|
||||
case ast.LocalDate:
|
||||
return unmarshalLocalDate(x, node)
|
||||
default:
|
||||
panic(fmt.Sprintf("unmarshalValue: unhandled unmarshalValue kind %s", node.Kind))
|
||||
panic(fmt.Sprintf("unhandled node kind %s", node.Kind))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,7 +386,9 @@ func unmarshalLocalDate(x target, node ast.Node) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return setDate(x, v)
|
||||
setDate(x, v)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshalLocalDateTime(x target, node ast.Node) error {
|
||||
@@ -421,7 +403,9 @@ func unmarshalLocalDateTime(x target, node ast.Node) error {
|
||||
return newDecodeError(rest, "extra characters at the end of a local date time")
|
||||
}
|
||||
|
||||
return setLocalDateTime(x, v)
|
||||
setLocalDateTime(x, v)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshalDateTime(x target, node ast.Node) error {
|
||||
@@ -432,48 +416,37 @@ func unmarshalDateTime(x target, node ast.Node) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return setDateTime(x, v)
|
||||
setDateTime(x, v)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setLocalDateTime(x target, v LocalDateTime) error {
|
||||
func setLocalDateTime(x target, v LocalDateTime) {
|
||||
if x.get().Type() == timeType {
|
||||
cast := v.In(time.Local)
|
||||
|
||||
return setDateTime(x, cast)
|
||||
setDateTime(x, cast)
|
||||
return
|
||||
}
|
||||
|
||||
err := x.set(reflect.ValueOf(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("setLocalDateTime: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
x.set(reflect.ValueOf(v))
|
||||
}
|
||||
|
||||
func setDateTime(x target, v time.Time) error {
|
||||
err := x.set(reflect.ValueOf(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("setDateTime: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
func setDateTime(x target, v time.Time) {
|
||||
x.set(reflect.ValueOf(v))
|
||||
}
|
||||
|
||||
var timeType = reflect.TypeOf(time.Time{})
|
||||
|
||||
func setDate(x target, v LocalDate) error {
|
||||
func setDate(x target, v LocalDate) {
|
||||
if x.get().Type() == timeType {
|
||||
cast := v.In(time.Local)
|
||||
|
||||
return setDateTime(x, cast)
|
||||
setDateTime(x, cast)
|
||||
return
|
||||
}
|
||||
|
||||
err := x.set(reflect.ValueOf(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("setDate: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
x.set(reflect.ValueOf(v))
|
||||
}
|
||||
|
||||
func unmarshalString(x target, node ast.Node) error {
|
||||
@@ -514,10 +487,7 @@ func unmarshalFloat(x target, node ast.Node) error {
|
||||
func (d *decoder) unmarshalInlineTable(x target, node ast.Node) error {
|
||||
assertNode(ast.InlineTable, node)
|
||||
|
||||
err := ensureMapIfInterface(x)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshalInlineTable: %w", err)
|
||||
}
|
||||
ensureMapIfInterface(x)
|
||||
|
||||
it := node.Children()
|
||||
for it.Next() {
|
||||
@@ -546,10 +516,7 @@ func (d *decoder) unmarshalArray(x target, node ast.Node) error {
|
||||
for it.Next() {
|
||||
n := it.Node()
|
||||
|
||||
v, err := elementAt(x, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v := elementAt(x, idx)
|
||||
|
||||
if v == nil {
|
||||
// when we go out of bound for an array just stop processing it to
|
||||
|
||||
Reference in New Issue
Block a user