vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
author Mikael Berthe <mikael@lilotux.net>
Tue, 23 Aug 2022 22:39:43 +0200
changeset 260 445e01aede7e
child 262 8d3354485fc3
permissions -rw-r--r--
Update vendor directory
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
package toml
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
import (
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
	"encoding"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
	"errors"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
	"fmt"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
	"io"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
	"io/ioutil"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
	"math"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
	"reflect"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
	"strings"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
	"sync/atomic"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
	"time"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
	"github.com/pelletier/go-toml/v2/internal/ast"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
	"github.com/pelletier/go-toml/v2/internal/danger"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
	"github.com/pelletier/go-toml/v2/internal/tracker"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
// Unmarshal deserializes a TOML document into a Go value.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
// It is a shortcut for Decoder.Decode() with the default options.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
func Unmarshal(data []byte, v interface{}) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
	p := parser{}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
	p.Reset(data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
	d := decoder{p: &p}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
	return d.FromParser(v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
// Decoder reads and decode a TOML document from an input stream.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
type Decoder struct {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
	// input
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
	r io.Reader
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
	// global settings
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
	strict bool
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
// NewDecoder creates a new Decoder that will read from r.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
func NewDecoder(r io.Reader) *Decoder {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
	return &Decoder{r: r}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
// DisallowUnknownFields causes the Decoder to return an error when the
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
// destination is a struct and the input contains a key that does not match a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
// non-ignored field.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
// In that case, the Decoder returns a StrictMissingError that can be used to
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
// retrieve the individual errors as well as generate a human readable
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
// description of the missing fields.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
func (d *Decoder) DisallowUnknownFields() *Decoder {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
	d.strict = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
	return d
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
// Decode the whole content of r into v.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
// By default, values in the document that don't exist in the target Go value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
// are ignored. See Decoder.DisallowUnknownFields() to change this behavior.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
// When a TOML local date, time, or date-time is decoded into a time.Time, its
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
// value is represented in time.Local timezone. Otherwise the approriate Local*
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
// structure is used. For time values, precision up to the nanosecond is
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
// supported by truncating extra digits.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
// Empty tables decoded in an interface{} create an empty initialized
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
// map[string]interface{}.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
// Types implementing the encoding.TextUnmarshaler interface are decoded from a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
// TOML string.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
// When decoding a number, go-toml will return an error if the number is out of
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
// bounds for the target type (which includes negative numbers when decoding
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
// into an unsigned int).
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
// If an error occurs while decoding the content of the document, this function
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
// returns a toml.DecodeError, providing context about the issue. When using
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
// strict mode and a field is missing, a `toml.StrictMissingError` is
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
// returned. In any other case, this function returns a standard Go error.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
// # Type mapping
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
// List of supported TOML types and their associated accepted Go types:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
//	String           -> string
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
//	Integer          -> uint*, int*, depending on size
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
//	Float            -> float*, depending on size
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
//	Boolean          -> bool
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
//	Offset Date-Time -> time.Time
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
//	Local Date-time  -> LocalDateTime, time.Time
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
//	Local Date       -> LocalDate, time.Time
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
//	Local Time       -> LocalTime, time.Time
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
//	Array            -> slice and array, depending on elements types
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
//	Table            -> map and struct
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
//	Inline Table     -> same as Table
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
//	Array of Tables  -> same as Array and Table
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
func (d *Decoder) Decode(v interface{}) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
	b, err := ioutil.ReadAll(d.r)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
	if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
		return fmt.Errorf("toml: %w", err)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
	p := parser{}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
	p.Reset(b)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	dec := decoder{
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
		p: &p,
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
		strict: strict{
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
			Enabled: d.strict,
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
		},
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	return dec.FromParser(v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
type decoder struct {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
	// Which parser instance in use for this decoding session.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
	p *parser
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	// Flag indicating that the current expression is stashed.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
	// If set to true, calling nextExpr will not actually pull a new expression
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
	// but turn off the flag instead.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
	stashedExpr bool
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
	// Skip expressions until a table is found. This is set to true when a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
	// table could not be create (missing field in map), so all KV expressions
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
	// need to be skipped.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	skipUntilTable bool
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
	// Tracks position in Go arrays.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
	// This is used when decoding [[array tables]] into Go arrays. Given array
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
	// tables are separate TOML expression, we need to keep track of where we
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
	// are at in the Go array, as we can't just introspect its size.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
	arrayIndexes map[reflect.Value]int
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
	// Tracks keys that have been seen, with which type.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
	seen tracker.SeenTracker
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
	// Strict mode
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	strict strict
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
	// Current context for the error.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
	errorContext *errorContext
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
type errorContext struct {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
	Struct reflect.Type
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
	Field  []int
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
func (d *decoder) typeMismatchError(toml string, target reflect.Type) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
	if d.errorContext != nil && d.errorContext.Struct != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
		ctx := d.errorContext
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
		f := ctx.Struct.FieldByIndex(ctx.Field)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
		return fmt.Errorf("toml: cannot decode TOML %s into struct field %s.%s of type %s", toml, ctx.Struct, f.Name, f.Type)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
	return fmt.Errorf("toml: cannot decode TOML %s into a Go value of type %s", toml, target)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
func (d *decoder) expr() *ast.Node {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
	return d.p.Expression()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
func (d *decoder) nextExpr() bool {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
	if d.stashedExpr {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
		d.stashedExpr = false
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
		return true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
	return d.p.NextExpression()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
func (d *decoder) stashExpr() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
	d.stashedExpr = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
func (d *decoder) arrayIndex(shouldAppend bool, v reflect.Value) int {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
	if d.arrayIndexes == nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
		d.arrayIndexes = make(map[reflect.Value]int, 1)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
	idx, ok := d.arrayIndexes[v]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
	if !ok {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
		d.arrayIndexes[v] = 0
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
	} else if shouldAppend {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
		idx++
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
		d.arrayIndexes[v] = idx
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
	return idx
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
func (d *decoder) FromParser(v interface{}) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
	r := reflect.ValueOf(v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
	if r.Kind() != reflect.Ptr {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
		return fmt.Errorf("toml: decoding can only be performed into a pointer, not %s", r.Kind())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
	if r.IsNil() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
		return fmt.Errorf("toml: decoding pointer target cannot be nil")
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
	r = r.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
	if r.Kind() == reflect.Interface && r.IsNil() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
		newMap := map[string]interface{}{}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
		r.Set(reflect.ValueOf(newMap))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
	err := d.fromParser(r)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
	if err == nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
		return d.strict.Error(d.p.data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
	var e *decodeError
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
	if errors.As(err, &e) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
		return wrapDecodeError(d.p.data, e)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
	return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
func (d *decoder) fromParser(root reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
	for d.nextExpr() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
		err := d.handleRootExpression(d.expr(), root)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
			return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
	return d.p.Error()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
/*
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
Rules for the unmarshal code:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
- The stack is used to keep track of which values need to be set where.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
- handle* functions <=> switch on a given ast.Kind.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
- unmarshalX* functions need to unmarshal a node of kind X.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
- An "object" is either a struct or a map.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
*/
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
func (d *decoder) handleRootExpression(expr *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
	var x reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
	var err error
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
	if !(d.skipUntilTable && expr.Kind == ast.KeyValue) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
		err = d.seen.CheckExpression(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
			return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
	switch expr.Kind {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
	case ast.KeyValue:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
		if d.skipUntilTable {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
			return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
		x, err = d.handleKeyValue(expr, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
	case ast.Table:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
		d.skipUntilTable = false
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
		d.strict.EnterTable(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
		x, err = d.handleTable(expr.Key(), v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
	case ast.ArrayTable:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
		d.skipUntilTable = false
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
		d.strict.EnterArrayTable(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
		x, err = d.handleArrayTable(expr.Key(), v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
		panic(fmt.Errorf("parser should not permit expression of kind %s at document root", expr.Kind))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   269
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
	if d.skipUntilTable {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
		if expr.Kind == ast.Table || expr.Kind == ast.ArrayTable {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
			d.strict.MissingTable(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
	} else if err == nil && x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
		v.Set(x)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   277
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   278
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   279
	return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   280
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   281
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   282
func (d *decoder) handleArrayTable(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
	if key.Next() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
		return d.handleArrayTablePart(key, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
	return d.handleKeyValues(v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
func (d *decoder) handleArrayTableCollectionLast(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
		elem := v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
		if !elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
			elem = reflect.New(sliceInterfaceType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   295
			elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   296
		} else if elem.Kind() == reflect.Slice {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   297
			if elem.Type() != sliceInterfaceType {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   298
				elem = reflect.New(sliceInterfaceType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   299
				elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   300
			} else if !elem.CanSet() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   301
				nelem := reflect.New(sliceInterfaceType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   302
				nelem.Set(reflect.MakeSlice(sliceInterfaceType, elem.Len(), elem.Cap()))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   303
				reflect.Copy(nelem, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
				elem = nelem
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   306
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
		return d.handleArrayTableCollectionLast(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
	case reflect.Ptr:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   309
		elem := v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   310
		if !elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   311
			ptr := reflect.New(v.Type().Elem())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
			v.Set(ptr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
			elem = ptr.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   314
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   315
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   316
		elem, err := d.handleArrayTableCollectionLast(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   317
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   318
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   319
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   320
		v.Elem().Set(elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   321
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   322
		return v, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   323
	case reflect.Slice:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   324
		elemType := v.Type().Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   325
		var elem reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   326
		if elemType.Kind() == reflect.Interface {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   327
			elem = makeMapStringInterface()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   328
		} else {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   329
			elem = reflect.New(elemType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   330
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
		elem2, err := d.handleArrayTable(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   332
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   335
		if elem2.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   336
			elem = elem2
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   337
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   338
		return reflect.Append(v, elem), nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   339
	case reflect.Array:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   340
		idx := d.arrayIndex(true, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   341
		if idx >= v.Len() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   342
			return v, fmt.Errorf("toml: cannot decode array table into %s at position %d", v.Type(), idx)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   343
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   344
		elem := v.Index(idx)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   345
		_, err := d.handleArrayTable(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   346
		return v, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   347
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   348
		return reflect.Value{}, fmt.Errorf("toml: cannot decode array table into a %s", v.Type())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   349
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   350
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   351
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   352
// When parsing an array table expression, each part of the key needs to be
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   353
// evaluated like a normal key, but if it returns a collection, it also needs to
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   354
// point to the last element of the collection. Unless it is the last part of
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   355
// the key, then it needs to create a new element at the end.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   356
func (d *decoder) handleArrayTableCollection(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   357
	if key.IsLast() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   358
		return d.handleArrayTableCollectionLast(key, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   359
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   360
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   361
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   362
	case reflect.Ptr:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   363
		elem := v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   364
		if !elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   365
			ptr := reflect.New(v.Type().Elem())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   366
			v.Set(ptr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   367
			elem = ptr.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   368
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   369
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   370
		elem, err := d.handleArrayTableCollection(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   371
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   372
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   373
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
		if elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   375
			v.Elem().Set(elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
		return v, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
	case reflect.Slice:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   380
		elem := v.Index(v.Len() - 1)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   381
		x, err := d.handleArrayTable(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
		if err != nil || d.skipUntilTable {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   386
			elem.Set(x)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
		return v, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   390
	case reflect.Array:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   391
		idx := d.arrayIndex(false, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   392
		if idx >= v.Len() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   393
			return v, fmt.Errorf("toml: cannot decode array table into %s at position %d", v.Type(), idx)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   394
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
		elem := v.Index(idx)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
		_, err := d.handleArrayTable(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   397
		return v, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   398
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   399
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   400
	return d.handleArrayTable(key, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   401
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   402
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   403
func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   404
	var rv reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   405
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   406
	// First, dispatch over v to make sure it is a valid object.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   407
	// There is no guarantee over what it could be.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   408
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   409
	case reflect.Ptr:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   410
		elem := v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   411
		if !elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   412
			v.Set(reflect.New(v.Type().Elem()))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   413
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   414
		elem = v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   415
		return d.handleKeyPart(key, elem, nextFn, makeFn)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   416
	case reflect.Map:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   417
		vt := v.Type()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   418
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   419
		// Create the key for the map element. Convert to key type.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   420
		mk := reflect.ValueOf(string(key.Node().Data)).Convert(vt.Key())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   421
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   422
		// If the map does not exist, create it.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   423
		if v.IsNil() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   424
			vt := v.Type()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   425
			v = reflect.MakeMap(vt)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   426
			rv = v
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   427
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   428
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   429
		mv := v.MapIndex(mk)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   430
		set := false
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   431
		if !mv.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   432
			// If there is no value in the map, create a new one according to
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   433
			// the map type. If the element type is interface, create either a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   434
			// map[string]interface{} or a []interface{} depending on whether
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   435
			// this is the last part of the array table key.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   436
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   437
			t := vt.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   438
			if t.Kind() == reflect.Interface {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   439
				mv = makeFn()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   440
			} else {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   441
				mv = reflect.New(t).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   442
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   443
			set = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   444
		} else if mv.Kind() == reflect.Interface {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   445
			mv = mv.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   446
			if !mv.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   447
				mv = makeFn()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   448
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   449
			set = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   450
		} else if !mv.CanAddr() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   451
			vt := v.Type()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   452
			t := vt.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   453
			oldmv := mv
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   454
			mv = reflect.New(t).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   455
			mv.Set(oldmv)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   456
			set = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   457
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   458
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   459
		x, err := nextFn(key, mv)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   460
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   461
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   462
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   463
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   464
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   465
			mv = x
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   466
			set = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   467
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   468
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   469
		if set {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   470
			v.SetMapIndex(mk, mv)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   471
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   472
	case reflect.Struct:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   473
		path, found := structFieldPath(v, string(key.Node().Data))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   474
		if !found {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   475
			d.skipUntilTable = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   476
			return reflect.Value{}, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   477
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   478
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   479
		if d.errorContext == nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   480
			d.errorContext = new(errorContext)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   481
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   482
		t := v.Type()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   483
		d.errorContext.Struct = t
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   484
		d.errorContext.Field = path
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   485
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   486
		f := v.FieldByIndex(path)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   487
		x, err := nextFn(key, f)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   488
		if err != nil || d.skipUntilTable {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   489
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   490
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   491
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   492
			f.Set(x)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   493
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   494
		d.errorContext.Field = nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   495
		d.errorContext.Struct = nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   496
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   497
		if v.Elem().IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   498
			v = v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   499
		} else {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   500
			v = makeMapStringInterface()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   501
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   502
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   503
		x, err := d.handleKeyPart(key, v, nextFn, makeFn)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   504
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   505
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   506
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   507
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   508
			v = x
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   509
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   510
		rv = v
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   511
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   512
		panic(fmt.Errorf("unhandled part: %s", v.Kind()))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   513
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   514
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   515
	return rv, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   516
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   517
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   518
// HandleArrayTablePart navigates the Go structure v using the key v. It is
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   519
// only used for the prefix (non-last) parts of an array-table. When
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   520
// encountering a collection, it should go to the last element.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   521
func (d *decoder) handleArrayTablePart(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   522
	var makeFn valueMakerFn
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   523
	if key.IsLast() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   524
		makeFn = makeSliceInterface
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   525
	} else {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   526
		makeFn = makeMapStringInterface
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   527
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   528
	return d.handleKeyPart(key, v, d.handleArrayTableCollection, makeFn)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   529
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   530
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   531
// HandleTable returns a reference when it has checked the next expression but
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   532
// cannot handle it.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   533
func (d *decoder) handleTable(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   534
	if v.Kind() == reflect.Slice {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   535
		if v.Len() == 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   536
			return reflect.Value{}, newDecodeError(key.Node().Data, "cannot store a table in a slice")
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   537
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   538
		elem := v.Index(v.Len() - 1)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   539
		x, err := d.handleTable(key, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   540
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   541
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   542
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   543
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   544
			elem.Set(x)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   545
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   546
		return reflect.Value{}, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   547
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   548
	if key.Next() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   549
		// Still scoping the key
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   550
		return d.handleTablePart(key, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   551
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   552
	// Done scoping the key.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   553
	// Now handle all the key-value expressions in this table.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   554
	return d.handleKeyValues(v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   555
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   556
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   557
// Handle root expressions until the end of the document or the next
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   558
// non-key-value.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   559
func (d *decoder) handleKeyValues(v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   560
	var rv reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   561
	for d.nextExpr() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   562
		expr := d.expr()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   563
		if expr.Kind != ast.KeyValue {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   564
			// Stash the expression so that fromParser can just loop and use
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   565
			// the right handler.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   566
			// We could just recurse ourselves here, but at least this gives a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   567
			// chance to pop the stack a bit.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   568
			d.stashExpr()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   569
			break
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   570
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   571
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   572
		err := d.seen.CheckExpression(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   573
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   574
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   575
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   576
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   577
		x, err := d.handleKeyValue(expr, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   578
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   579
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   580
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   581
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   582
			v = x
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   583
			rv = x
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   584
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   585
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   586
	return rv, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   587
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   588
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   589
type (
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   590
	handlerFn    func(key ast.Iterator, v reflect.Value) (reflect.Value, error)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   591
	valueMakerFn func() reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   592
)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   593
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   594
func makeMapStringInterface() reflect.Value {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   595
	return reflect.MakeMap(mapStringInterfaceType)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   596
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   597
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   598
func makeSliceInterface() reflect.Value {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   599
	return reflect.MakeSlice(sliceInterfaceType, 0, 16)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   600
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   601
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   602
func (d *decoder) handleTablePart(key ast.Iterator, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   603
	return d.handleKeyPart(key, v, d.handleTable, makeMapStringInterface)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   604
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   605
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   606
func (d *decoder) tryTextUnmarshaler(node *ast.Node, v reflect.Value) (bool, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   607
	// Special case for time, because we allow to unmarshal to it from
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   608
	// different kind of AST nodes.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   609
	if v.Type() == timeType {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   610
		return false, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   611
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   612
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   613
	if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   614
		err := v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   615
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   616
			return false, newDecodeError(d.p.Raw(node.Raw), "%w", err)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   617
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   618
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   619
		return true, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   620
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   621
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   622
	return false, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   623
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   624
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   625
func (d *decoder) handleValue(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   626
	for v.Kind() == reflect.Ptr {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   627
		v = initAndDereferencePointer(v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   628
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   629
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   630
	ok, err := d.tryTextUnmarshaler(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   631
	if ok || err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   632
		return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   633
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   634
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   635
	switch value.Kind {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   636
	case ast.String:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   637
		return d.unmarshalString(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   638
	case ast.Integer:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   639
		return d.unmarshalInteger(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   640
	case ast.Float:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   641
		return d.unmarshalFloat(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   642
	case ast.Bool:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   643
		return d.unmarshalBool(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   644
	case ast.DateTime:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   645
		return d.unmarshalDateTime(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   646
	case ast.LocalDate:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   647
		return d.unmarshalLocalDate(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   648
	case ast.LocalTime:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   649
		return d.unmarshalLocalTime(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   650
	case ast.LocalDateTime:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   651
		return d.unmarshalLocalDateTime(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   652
	case ast.InlineTable:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   653
		return d.unmarshalInlineTable(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   654
	case ast.Array:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   655
		return d.unmarshalArray(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   656
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   657
		panic(fmt.Errorf("handleValue not implemented for %s", value.Kind))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   658
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   659
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   660
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   661
func (d *decoder) unmarshalArray(array *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   662
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   663
	case reflect.Slice:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   664
		if v.IsNil() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   665
			v.Set(reflect.MakeSlice(v.Type(), 0, 16))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   666
		} else {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   667
			v.SetLen(0)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   668
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   669
	case reflect.Array:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   670
		// arrays are always initialized
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   671
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   672
		elem := v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   673
		if !elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   674
			elem = reflect.New(sliceInterfaceType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   675
			elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   676
		} else if elem.Kind() == reflect.Slice {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   677
			if elem.Type() != sliceInterfaceType {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   678
				elem = reflect.New(sliceInterfaceType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   679
				elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   680
			} else if !elem.CanSet() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   681
				nelem := reflect.New(sliceInterfaceType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   682
				nelem.Set(reflect.MakeSlice(sliceInterfaceType, elem.Len(), elem.Cap()))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   683
				reflect.Copy(nelem, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   684
				elem = nelem
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   685
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   686
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   687
		err := d.unmarshalArray(array, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   688
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   689
			return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   690
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   691
		v.Set(elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   692
		return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   693
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   694
		// TODO: use newDecodeError, but first the parser needs to fill
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   695
		//   array.Data.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   696
		return d.typeMismatchError("array", v.Type())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   697
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   698
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   699
	elemType := v.Type().Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   700
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   701
	it := array.Children()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   702
	idx := 0
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   703
	for it.Next() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   704
		n := it.Node()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   705
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   706
		// TODO: optimize
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   707
		if v.Kind() == reflect.Slice {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   708
			elem := reflect.New(elemType).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   709
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   710
			err := d.handleValue(n, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   711
			if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   712
				return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   713
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   714
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   715
			v.Set(reflect.Append(v, elem))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   716
		} else { // array
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   717
			if idx >= v.Len() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   718
				return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   719
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   720
			elem := v.Index(idx)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   721
			err := d.handleValue(n, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   722
			if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   723
				return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   724
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   725
			idx++
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   726
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   727
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   728
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   729
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   730
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   731
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   732
func (d *decoder) unmarshalInlineTable(itable *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   733
	// Make sure v is an initialized object.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   734
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   735
	case reflect.Map:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   736
		if v.IsNil() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   737
			v.Set(reflect.MakeMap(v.Type()))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   738
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   739
	case reflect.Struct:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   740
	// structs are always initialized.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   741
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   742
		elem := v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   743
		if !elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   744
			elem = makeMapStringInterface()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   745
			v.Set(elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   746
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   747
		return d.unmarshalInlineTable(itable, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   748
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   749
		return newDecodeError(itable.Data, "cannot store inline table in Go type %s", v.Kind())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   750
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   751
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   752
	it := itable.Children()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   753
	for it.Next() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   754
		n := it.Node()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   755
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   756
		x, err := d.handleKeyValue(n, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   757
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   758
			return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   759
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   760
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   761
			v = x
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   762
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   763
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   764
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   765
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   766
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   767
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   768
func (d *decoder) unmarshalDateTime(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   769
	dt, err := parseDateTime(value.Data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   770
	if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   771
		return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   772
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   773
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   774
	v.Set(reflect.ValueOf(dt))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   775
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   776
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   777
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   778
func (d *decoder) unmarshalLocalDate(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   779
	ld, err := parseLocalDate(value.Data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   780
	if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   781
		return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   782
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   783
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   784
	if v.Type() == timeType {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   785
		cast := ld.AsTime(time.Local)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   786
		v.Set(reflect.ValueOf(cast))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   787
		return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   788
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   789
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   790
	v.Set(reflect.ValueOf(ld))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   791
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   792
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   793
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   794
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   795
func (d *decoder) unmarshalLocalTime(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   796
	lt, rest, err := parseLocalTime(value.Data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   797
	if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   798
		return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   799
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   800
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   801
	if len(rest) > 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   802
		return newDecodeError(rest, "extra characters at the end of a local time")
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   803
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   804
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   805
	v.Set(reflect.ValueOf(lt))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   806
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   807
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   808
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   809
func (d *decoder) unmarshalLocalDateTime(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   810
	ldt, rest, err := parseLocalDateTime(value.Data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   811
	if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   812
		return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   813
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   814
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   815
	if len(rest) > 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   816
		return newDecodeError(rest, "extra characters at the end of a local date time")
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   817
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   818
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   819
	if v.Type() == timeType {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   820
		cast := ldt.AsTime(time.Local)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   821
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   822
		v.Set(reflect.ValueOf(cast))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   823
		return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   824
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   825
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   826
	v.Set(reflect.ValueOf(ldt))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   827
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   828
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   829
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   830
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   831
func (d *decoder) unmarshalBool(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   832
	b := value.Data[0] == 't'
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   833
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   834
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   835
	case reflect.Bool:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   836
		v.SetBool(b)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   837
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   838
		v.Set(reflect.ValueOf(b))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   839
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   840
		return newDecodeError(value.Data, "cannot assign boolean to a %t", b)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   841
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   842
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   843
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   844
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   845
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   846
func (d *decoder) unmarshalFloat(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   847
	f, err := parseFloat(value.Data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   848
	if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   849
		return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   850
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   851
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   852
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   853
	case reflect.Float64:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   854
		v.SetFloat(f)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   855
	case reflect.Float32:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   856
		if f > math.MaxFloat32 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   857
			return newDecodeError(value.Data, "number %f does not fit in a float32", f)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   858
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   859
		v.SetFloat(f)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   860
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   861
		v.Set(reflect.ValueOf(f))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   862
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   863
		return newDecodeError(value.Data, "float cannot be assigned to %s", v.Kind())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   864
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   865
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   866
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   867
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   868
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   869
const (
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   870
	maxInt = int64(^uint(0) >> 1)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   871
	minInt = -maxInt - 1
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   872
)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   873
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   874
// Maximum value of uint for decoding. Currently the decoder parses the integer
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   875
// into an int64. As a result, on architectures where uint is 64 bits, the
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   876
// effective maximum uint we can decode is the maximum of int64. On
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   877
// architectures where uint is 32 bits, the maximum value we can decode is
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   878
// lower: the maximum of uint32. I didn't find a way to figure out this value at
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   879
// compile time, so it is computed during initialization.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   880
var maxUint int64 = math.MaxInt64
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   881
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   882
func init() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   883
	m := uint64(^uint(0))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   884
	if m < uint64(maxUint) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   885
		maxUint = int64(m)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   886
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   887
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   888
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   889
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   890
	i, err := parseInteger(value.Data)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   891
	if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   892
		return err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   893
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   894
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   895
	var r reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   896
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   897
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   898
	case reflect.Int64:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   899
		v.SetInt(i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   900
		return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   901
	case reflect.Int32:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   902
		if i < math.MinInt32 || i > math.MaxInt32 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   903
			return fmt.Errorf("toml: number %d does not fit in an int32", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   904
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   905
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   906
		r = reflect.ValueOf(int32(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   907
	case reflect.Int16:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   908
		if i < math.MinInt16 || i > math.MaxInt16 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   909
			return fmt.Errorf("toml: number %d does not fit in an int16", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   910
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   911
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   912
		r = reflect.ValueOf(int16(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   913
	case reflect.Int8:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   914
		if i < math.MinInt8 || i > math.MaxInt8 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   915
			return fmt.Errorf("toml: number %d does not fit in an int8", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   916
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   917
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   918
		r = reflect.ValueOf(int8(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   919
	case reflect.Int:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   920
		if i < minInt || i > maxInt {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   921
			return fmt.Errorf("toml: number %d does not fit in an int", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   922
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   923
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   924
		r = reflect.ValueOf(int(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   925
	case reflect.Uint64:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   926
		if i < 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   927
			return fmt.Errorf("toml: negative number %d does not fit in an uint64", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   928
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   929
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   930
		r = reflect.ValueOf(uint64(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   931
	case reflect.Uint32:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   932
		if i < 0 || i > math.MaxUint32 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   933
			return fmt.Errorf("toml: negative number %d does not fit in an uint32", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   934
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   935
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   936
		r = reflect.ValueOf(uint32(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   937
	case reflect.Uint16:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   938
		if i < 0 || i > math.MaxUint16 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   939
			return fmt.Errorf("toml: negative number %d does not fit in an uint16", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   940
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   941
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   942
		r = reflect.ValueOf(uint16(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   943
	case reflect.Uint8:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   944
		if i < 0 || i > math.MaxUint8 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   945
			return fmt.Errorf("toml: negative number %d does not fit in an uint8", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   946
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   947
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   948
		r = reflect.ValueOf(uint8(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   949
	case reflect.Uint:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   950
		if i < 0 || i > maxUint {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   951
			return fmt.Errorf("toml: negative number %d does not fit in an uint", i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   952
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   953
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   954
		r = reflect.ValueOf(uint(i))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   955
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   956
		r = reflect.ValueOf(i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   957
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   958
		return d.typeMismatchError("integer", v.Type())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   959
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   960
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   961
	if !r.Type().AssignableTo(v.Type()) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   962
		r = r.Convert(v.Type())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   963
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   964
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   965
	v.Set(r)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   966
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   967
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   968
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   969
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   970
func (d *decoder) unmarshalString(value *ast.Node, v reflect.Value) error {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   971
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   972
	case reflect.String:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   973
		v.SetString(string(value.Data))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   974
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   975
		v.Set(reflect.ValueOf(string(value.Data)))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   976
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   977
		return newDecodeError(d.p.Raw(value.Raw), "cannot store TOML string into a Go %s", v.Kind())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   978
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   979
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   980
	return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   981
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   982
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   983
func (d *decoder) handleKeyValue(expr *ast.Node, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   984
	d.strict.EnterKeyValue(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   985
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   986
	v, err := d.handleKeyValueInner(expr.Key(), expr.Value(), v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   987
	if d.skipUntilTable {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   988
		d.strict.MissingField(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   989
		d.skipUntilTable = false
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   990
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   991
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   992
	d.strict.ExitKeyValue(expr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   993
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   994
	return v, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   995
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   996
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   997
func (d *decoder) handleKeyValueInner(key ast.Iterator, value *ast.Node, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   998
	if key.Next() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   999
		// Still scoping the key
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1000
		return d.handleKeyValuePart(key, value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1001
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1002
	// Done scoping the key.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1003
	// v is whatever Go value we need to fill.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1004
	return reflect.Value{}, d.handleValue(value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1005
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1006
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1007
func (d *decoder) handleKeyValuePart(key ast.Iterator, value *ast.Node, v reflect.Value) (reflect.Value, error) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1008
	// contains the replacement for v
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1009
	var rv reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1010
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1011
	// First, dispatch over v to make sure it is a valid object.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1012
	// There is no guarantee over what it could be.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1013
	switch v.Kind() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1014
	case reflect.Map:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1015
		vt := v.Type()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1016
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1017
		mk := reflect.ValueOf(string(key.Node().Data))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1018
		mkt := stringType
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1019
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1020
		keyType := vt.Key()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1021
		if !mkt.AssignableTo(keyType) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1022
			if !mkt.ConvertibleTo(keyType) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1023
				return reflect.Value{}, fmt.Errorf("toml: cannot convert map key of type %s to expected type %s", mkt, keyType)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1024
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1025
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1026
			mk = mk.Convert(keyType)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1027
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1028
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1029
		// If the map does not exist, create it.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1030
		if v.IsNil() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1031
			v = reflect.MakeMap(vt)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1032
			rv = v
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1033
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1034
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1035
		mv := v.MapIndex(mk)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1036
		set := false
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1037
		if !mv.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1038
			set = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1039
			mv = reflect.New(v.Type().Elem()).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1040
		} else {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1041
			if key.IsLast() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1042
				var x interface{}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1043
				mv = reflect.ValueOf(&x).Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1044
				set = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1045
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1046
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1047
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1048
		nv, err := d.handleKeyValueInner(key, value, mv)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1049
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1050
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1051
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1052
		if nv.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1053
			mv = nv
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1054
			set = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1055
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1056
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1057
		if set {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1058
			v.SetMapIndex(mk, mv)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1059
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1060
	case reflect.Struct:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1061
		path, found := structFieldPath(v, string(key.Node().Data))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1062
		if !found {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1063
			d.skipUntilTable = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1064
			break
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1065
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1066
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1067
		if d.errorContext == nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1068
			d.errorContext = new(errorContext)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1069
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1070
		t := v.Type()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1071
		d.errorContext.Struct = t
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1072
		d.errorContext.Field = path
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1073
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1074
		f := v.FieldByIndex(path)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1075
		x, err := d.handleKeyValueInner(key, value, f)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1076
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1077
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1078
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1079
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1080
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1081
			f.Set(x)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1082
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1083
		d.errorContext.Struct = nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1084
		d.errorContext.Field = nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1085
	case reflect.Interface:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1086
		v = v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1087
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1088
		// Following encoding/json: decoding an object into an
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1089
		// interface{}, it needs to always hold a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1090
		// map[string]interface{}. This is for the types to be
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1091
		// consistent whether a previous value was set or not.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1092
		if !v.IsValid() || v.Type() != mapStringInterfaceType {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1093
			v = makeMapStringInterface()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1094
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1095
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1096
		x, err := d.handleKeyValuePart(key, value, v)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1097
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1098
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1099
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1100
		if x.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1101
			v = x
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1102
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1103
		rv = v
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1104
	case reflect.Ptr:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1105
		elem := v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1106
		if !elem.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1107
			ptr := reflect.New(v.Type().Elem())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1108
			v.Set(ptr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1109
			rv = v
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1110
			elem = ptr.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1111
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1112
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1113
		elem2, err := d.handleKeyValuePart(key, value, elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1114
		if err != nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1115
			return reflect.Value{}, err
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1116
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1117
		if elem2.IsValid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1118
			elem = elem2
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1119
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1120
		v.Elem().Set(elem)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1121
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1122
		return reflect.Value{}, fmt.Errorf("unhandled kv part: %s", v.Kind())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1123
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1124
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1125
	return rv, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1126
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1127
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1128
func initAndDereferencePointer(v reflect.Value) reflect.Value {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1129
	var elem reflect.Value
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1130
	if v.IsNil() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1131
		ptr := reflect.New(v.Type().Elem())
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1132
		v.Set(ptr)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1133
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1134
	elem = v.Elem()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1135
	return elem
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1136
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1137
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1138
type fieldPathsMap = map[string][]int
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1139
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1140
var globalFieldPathsCache atomic.Value // map[danger.TypeID]fieldPathsMap
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1141
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1142
func structFieldPath(v reflect.Value, name string) ([]int, bool) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1143
	t := v.Type()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1144
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1145
	cache, _ := globalFieldPathsCache.Load().(map[danger.TypeID]fieldPathsMap)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1146
	fieldPaths, ok := cache[danger.MakeTypeID(t)]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1147
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1148
	if !ok {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1149
		fieldPaths = map[string][]int{}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1150
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1151
		forEachField(t, nil, func(name string, path []int) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1152
			fieldPaths[name] = path
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1153
			// extra copy for the case-insensitive match
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1154
			fieldPaths[strings.ToLower(name)] = path
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1155
		})
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1156
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1157
		newCache := make(map[danger.TypeID]fieldPathsMap, len(cache)+1)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1158
		newCache[danger.MakeTypeID(t)] = fieldPaths
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1159
		for k, v := range cache {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1160
			newCache[k] = v
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1161
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1162
		globalFieldPathsCache.Store(newCache)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1163
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1164
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1165
	path, ok := fieldPaths[name]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1166
	if !ok {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1167
		path, ok = fieldPaths[strings.ToLower(name)]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1168
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1169
	return path, ok
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1170
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1171
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1172
func forEachField(t reflect.Type, path []int, do func(name string, path []int)) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1173
	n := t.NumField()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1174
	for i := 0; i < n; i++ {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1175
		f := t.Field(i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1176
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1177
		if !f.Anonymous && f.PkgPath != "" {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1178
			// only consider exported fields.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1179
			continue
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1180
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1181
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1182
		fieldPath := append(path, i)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1183
		fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1184
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1185
		name := f.Tag.Get("toml")
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1186
		if name == "-" {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1187
			continue
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1188
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1189
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1190
		if i := strings.IndexByte(name, ','); i >= 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1191
			name = name[:i]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1192
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1193
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1194
		if f.Anonymous && name == "" {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1195
			forEachField(f.Type, fieldPath, do)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1196
			continue
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1197
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1198
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1199
		if name == "" {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1200
			name = f.Name
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1201
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1202
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1203
		do(name, fieldPath)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1204
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
  1205
}