mirror of
https://github.com/containers/podman.git
synced 2025-06-25 12:20:42 +08:00
Bump github.com/BurntSushi/toml from 1.1.0 to 1.2.0
Bumps [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) from 1.1.0 to 1.2.0. - [Release notes](https://github.com/BurntSushi/toml/releases) - [Commits](https://github.com/BurntSushi/toml/compare/v1.1.0...v1.2.0) --- updated-dependencies: - dependency-name: github.com/BurntSushi/toml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module github.com/containers/podman/v4
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.1.0
|
github.com/BurntSushi/toml v1.2.0
|
||||||
github.com/blang/semver/v4 v4.0.0
|
github.com/blang/semver/v4 v4.0.0
|
||||||
github.com/buger/goterm v1.0.4
|
github.com/buger/goterm v1.0.4
|
||||||
github.com/checkpoint-restore/checkpointctl v0.0.0-20220321135231-33f4a66335f0
|
github.com/checkpoint-restore/checkpointctl v0.0.0-20220321135231-33f4a66335f0
|
||||||
|
3
go.sum
3
go.sum
@ -102,8 +102,9 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp
|
|||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
|
||||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
|
||||||
|
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
|
2
vendor/github.com/BurntSushi/toml/.gitignore
generated
vendored
2
vendor/github.com/BurntSushi/toml/.gitignore
generated
vendored
@ -1,2 +1,2 @@
|
|||||||
toml.test
|
/toml.test
|
||||||
/toml-test
|
/toml-test
|
||||||
|
1
vendor/github.com/BurntSushi/toml/COMPATIBLE
generated
vendored
1
vendor/github.com/BurntSushi/toml/COMPATIBLE
generated
vendored
@ -1 +0,0 @@
|
|||||||
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
|
|
185
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
185
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
@ -1,6 +1,5 @@
|
|||||||
TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
|
TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
|
||||||
reflection interface similar to Go's standard library `json` and `xml`
|
reflection interface similar to Go's standard library `json` and `xml` packages.
|
||||||
packages.
|
|
||||||
|
|
||||||
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
|
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
|
||||||
|
|
||||||
@ -10,7 +9,7 @@ See the [releases page](https://github.com/BurntSushi/toml/releases) for a
|
|||||||
changelog; this information is also in the git tag annotations (e.g. `git show
|
changelog; this information is also in the git tag annotations (e.g. `git show
|
||||||
v0.4.0`).
|
v0.4.0`).
|
||||||
|
|
||||||
This library requires Go 1.13 or newer; install it with:
|
This library requires Go 1.13 or newer; add it to your go.mod with:
|
||||||
|
|
||||||
% go get github.com/BurntSushi/toml@latest
|
% go get github.com/BurntSushi/toml@latest
|
||||||
|
|
||||||
@ -19,16 +18,7 @@ It also comes with a TOML validator CLI tool:
|
|||||||
% go install github.com/BurntSushi/toml/cmd/tomlv@latest
|
% go install github.com/BurntSushi/toml/cmd/tomlv@latest
|
||||||
% tomlv some-toml-file.toml
|
% tomlv some-toml-file.toml
|
||||||
|
|
||||||
### Testing
|
|
||||||
This package passes all tests in [toml-test] for both the decoder and the
|
|
||||||
encoder.
|
|
||||||
|
|
||||||
[toml-test]: https://github.com/BurntSushi/toml-test
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
This package works similar to how the Go standard library handles XML and JSON.
|
|
||||||
Namely, data is loaded into Go values via reflection.
|
|
||||||
|
|
||||||
For the simplest example, consider some TOML file as just a list of keys and
|
For the simplest example, consider some TOML file as just a list of keys and
|
||||||
values:
|
values:
|
||||||
|
|
||||||
@ -40,7 +30,7 @@ Perfection = [ 6, 28, 496, 8128 ]
|
|||||||
DOB = 1987-07-05T05:45:00Z
|
DOB = 1987-07-05T05:45:00Z
|
||||||
```
|
```
|
||||||
|
|
||||||
Which could be defined in Go as:
|
Which can be decoded with:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@ -48,20 +38,15 @@ type Config struct {
|
|||||||
Cats []string
|
Cats []string
|
||||||
Pi float64
|
Pi float64
|
||||||
Perfection []int
|
Perfection []int
|
||||||
DOB time.Time // requires `import time`
|
DOB time.Time
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
And then decoded with:
|
|
||||||
|
|
||||||
```go
|
|
||||||
var conf Config
|
var conf Config
|
||||||
_, err := toml.Decode(tomlData, &conf)
|
_, err := toml.Decode(tomlData, &conf)
|
||||||
// handle error
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use struct tags if your struct field name doesn't map to a TOML
|
You can also use struct tags if your struct field name doesn't map to a TOML key
|
||||||
key value directly:
|
value directly:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
some_key_NAME = "wat"
|
some_key_NAME = "wat"
|
||||||
@ -73,139 +58,63 @@ type TOML struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Beware that like other most other decoders **only exported fields** are
|
Beware that like other decoders **only exported fields** are considered when
|
||||||
considered when encoding and decoding; private fields are silently ignored.
|
encoding and decoding; private fields are silently ignored.
|
||||||
|
|
||||||
### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces
|
### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces
|
||||||
Here's an example that automatically parses duration strings into
|
Here's an example that automatically parses values in a `mail.Address`:
|
||||||
`time.Duration` values:
|
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[song]]
|
contacts = [
|
||||||
name = "Thunder Road"
|
"Donald Duck <donald@duckburg.com>",
|
||||||
duration = "4m49s"
|
"Scrooge McDuck <scrooge@duckburg.com>",
|
||||||
|
]
|
||||||
[[song]]
|
|
||||||
name = "Stairway to Heaven"
|
|
||||||
duration = "8m03s"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Which can be decoded with:
|
Can be decoded with:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type song struct {
|
// Create address type which satisfies the encoding.TextUnmarshaler interface.
|
||||||
Name string
|
type address struct {
|
||||||
Duration duration
|
*mail.Address
|
||||||
}
|
|
||||||
type songs struct {
|
|
||||||
Song []song
|
|
||||||
}
|
|
||||||
var favorites songs
|
|
||||||
if _, err := toml.Decode(blob, &favorites); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range favorites.Song {
|
func (a *address) UnmarshalText(text []byte) error {
|
||||||
fmt.Printf("%s (%s)\n", s.Name, s.Duration)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
And you'll also need a `duration` type that satisfies the
|
|
||||||
`encoding.TextUnmarshaler` interface:
|
|
||||||
|
|
||||||
```go
|
|
||||||
type duration struct {
|
|
||||||
time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *duration) UnmarshalText(text []byte) error {
|
|
||||||
var err error
|
var err error
|
||||||
d.Duration, err = time.ParseDuration(string(text))
|
a.Address, err = mail.ParseAddress(string(text))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode it.
|
||||||
|
func decode() {
|
||||||
|
blob := `
|
||||||
|
contacts = [
|
||||||
|
"Donald Duck <donald@duckburg.com>",
|
||||||
|
"Scrooge McDuck <scrooge@duckburg.com>",
|
||||||
|
]
|
||||||
|
`
|
||||||
|
|
||||||
|
var contacts struct {
|
||||||
|
Contacts []address
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := toml.Decode(blob, &contacts)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range contacts.Contacts {
|
||||||
|
fmt.Printf("%#v\n", c.Address)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"}
|
||||||
|
// &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
To target TOML specifically you can implement `UnmarshalTOML` TOML interface in
|
To target TOML specifically you can implement `UnmarshalTOML` TOML interface in
|
||||||
a similar way.
|
a similar way.
|
||||||
|
|
||||||
### More complex usage
|
### More complex usage
|
||||||
Here's an example of how to load the example from the official spec page:
|
See the [`_example/`](/_example) directory for a more complex example.
|
||||||
|
|
||||||
```toml
|
|
||||||
# This is a TOML document. Boom.
|
|
||||||
|
|
||||||
title = "TOML Example"
|
|
||||||
|
|
||||||
[owner]
|
|
||||||
name = "Tom Preston-Werner"
|
|
||||||
organization = "GitHub"
|
|
||||||
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
|
||||||
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
|
||||||
|
|
||||||
[database]
|
|
||||||
server = "192.168.1.1"
|
|
||||||
ports = [ 8001, 8001, 8002 ]
|
|
||||||
connection_max = 5000
|
|
||||||
enabled = true
|
|
||||||
|
|
||||||
[servers]
|
|
||||||
|
|
||||||
# You can indent as you please. Tabs or spaces. TOML don't care.
|
|
||||||
[servers.alpha]
|
|
||||||
ip = "10.0.0.1"
|
|
||||||
dc = "eqdc10"
|
|
||||||
|
|
||||||
[servers.beta]
|
|
||||||
ip = "10.0.0.2"
|
|
||||||
dc = "eqdc10"
|
|
||||||
|
|
||||||
[clients]
|
|
||||||
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
|
|
||||||
|
|
||||||
# Line breaks are OK when inside arrays
|
|
||||||
hosts = [
|
|
||||||
"alpha",
|
|
||||||
"omega"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
And the corresponding Go types are:
|
|
||||||
|
|
||||||
```go
|
|
||||||
type tomlConfig struct {
|
|
||||||
Title string
|
|
||||||
Owner ownerInfo
|
|
||||||
DB database `toml:"database"`
|
|
||||||
Servers map[string]server
|
|
||||||
Clients clients
|
|
||||||
}
|
|
||||||
|
|
||||||
type ownerInfo struct {
|
|
||||||
Name string
|
|
||||||
Org string `toml:"organization"`
|
|
||||||
Bio string
|
|
||||||
DOB time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type database struct {
|
|
||||||
Server string
|
|
||||||
Ports []int
|
|
||||||
ConnMax int `toml:"connection_max"`
|
|
||||||
Enabled bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type server struct {
|
|
||||||
IP string
|
|
||||||
DC string
|
|
||||||
}
|
|
||||||
|
|
||||||
type clients struct {
|
|
||||||
Data [][]interface{}
|
|
||||||
Hosts []string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that a case insensitive match will be tried if an exact match can't be
|
|
||||||
found.
|
|
||||||
|
|
||||||
A working example of the above can be found in `_example/example.{go,toml}`.
|
|
||||||
|
227
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
227
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
@ -3,13 +3,16 @@ package toml
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unmarshaler is the interface implemented by objects that can unmarshal a
|
// Unmarshaler is the interface implemented by objects that can unmarshal a
|
||||||
@ -18,7 +21,7 @@ type Unmarshaler interface {
|
|||||||
UnmarshalTOML(interface{}) error
|
UnmarshalTOML(interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal decodes the contents of `p` in TOML format into a pointer `v`.
|
// Unmarshal decodes the contents of `data` in TOML format into a pointer `v`.
|
||||||
func Unmarshal(data []byte, v interface{}) error {
|
func Unmarshal(data []byte, v interface{}) error {
|
||||||
_, err := NewDecoder(bytes.NewReader(data)).Decode(v)
|
_, err := NewDecoder(bytes.NewReader(data)).Decode(v)
|
||||||
return err
|
return err
|
||||||
@ -75,6 +78,9 @@ const (
|
|||||||
// TOML datetimes correspond to Go time.Time values. Local datetimes are parsed
|
// TOML datetimes correspond to Go time.Time values. Local datetimes are parsed
|
||||||
// in the local timezone.
|
// in the local timezone.
|
||||||
//
|
//
|
||||||
|
// time.Duration types are treated as nanoseconds if the TOML value is an
|
||||||
|
// integer, or they're parsed with time.ParseDuration() if they're strings.
|
||||||
|
//
|
||||||
// All other TOML types (float, string, int, bool and array) correspond to the
|
// All other TOML types (float, string, int, bool and array) correspond to the
|
||||||
// obvious Go types.
|
// obvious Go types.
|
||||||
//
|
//
|
||||||
@ -82,7 +88,7 @@ const (
|
|||||||
// interface, in which case any primitive TOML value (floats, strings, integers,
|
// interface, in which case any primitive TOML value (floats, strings, integers,
|
||||||
// booleans, datetimes) will be converted to a []byte and given to the value's
|
// booleans, datetimes) will be converted to a []byte and given to the value's
|
||||||
// UnmarshalText method. See the Unmarshaler example for a demonstration with
|
// UnmarshalText method. See the Unmarshaler example for a demonstration with
|
||||||
// time duration strings.
|
// email addresses.
|
||||||
//
|
//
|
||||||
// Key mapping
|
// Key mapping
|
||||||
//
|
//
|
||||||
@ -111,6 +117,7 @@ func NewDecoder(r io.Reader) *Decoder {
|
|||||||
var (
|
var (
|
||||||
unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
|
unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
|
||||||
unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
|
unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
|
||||||
|
primitiveType = reflect.TypeOf((*Primitive)(nil)).Elem()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Decode TOML data in to the pointer `v`.
|
// Decode TOML data in to the pointer `v`.
|
||||||
@ -122,10 +129,10 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
|
|||||||
s = "%v"
|
s = "%v"
|
||||||
}
|
}
|
||||||
|
|
||||||
return MetaData{}, e("cannot decode to non-pointer "+s, reflect.TypeOf(v))
|
return MetaData{}, fmt.Errorf("toml: cannot decode to non-pointer "+s, reflect.TypeOf(v))
|
||||||
}
|
}
|
||||||
if rv.IsNil() {
|
if rv.IsNil() {
|
||||||
return MetaData{}, e("cannot decode to nil value of %q", reflect.TypeOf(v))
|
return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this is a supported type: struct, map, interface{}, or something
|
// Check if this is a supported type: struct, map, interface{}, or something
|
||||||
@ -135,7 +142,7 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
|
|||||||
if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map &&
|
if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map &&
|
||||||
!(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) &&
|
!(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) &&
|
||||||
!rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) {
|
!rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) {
|
||||||
return MetaData{}, e("cannot decode to type %s", rt)
|
return MetaData{}, fmt.Errorf("toml: cannot decode to type %s", rt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parser should read from io.Reader? Or at the very least, make it
|
// TODO: parser should read from io.Reader? Or at the very least, make it
|
||||||
@ -152,10 +159,11 @@ func (dec *Decoder) Decode(v interface{}) (MetaData, error) {
|
|||||||
|
|
||||||
md := MetaData{
|
md := MetaData{
|
||||||
mapping: p.mapping,
|
mapping: p.mapping,
|
||||||
types: p.types,
|
keyInfo: p.keyInfo,
|
||||||
keys: p.ordered,
|
keys: p.ordered,
|
||||||
decoded: make(map[string]struct{}, len(p.ordered)),
|
decoded: make(map[string]struct{}, len(p.ordered)),
|
||||||
context: nil,
|
context: nil,
|
||||||
|
data: data,
|
||||||
}
|
}
|
||||||
return md, md.unify(p.mapping, rv)
|
return md, md.unify(p.mapping, rv)
|
||||||
}
|
}
|
||||||
@ -185,7 +193,7 @@ func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error {
|
|||||||
func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
||||||
// Special case. Look for a `Primitive` value.
|
// Special case. Look for a `Primitive` value.
|
||||||
// TODO: #76 would make this superfluous after implemented.
|
// TODO: #76 would make this superfluous after implemented.
|
||||||
if rv.Type() == reflect.TypeOf((*Primitive)(nil)).Elem() {
|
if rv.Type() == primitiveType {
|
||||||
// Save the undecoded data and the key context into the primitive
|
// Save the undecoded data and the key context into the primitive
|
||||||
// value.
|
// value.
|
||||||
context := make(Key, len(md.context))
|
context := make(Key, len(md.context))
|
||||||
@ -197,17 +205,14 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case. Unmarshaler Interface support.
|
rvi := rv.Interface()
|
||||||
if rv.CanAddr() {
|
if v, ok := rvi.(Unmarshaler); ok {
|
||||||
if v, ok := rv.Addr().Interface().(Unmarshaler); ok {
|
return v.UnmarshalTOML(data)
|
||||||
return v.UnmarshalTOML(data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if v, ok := rvi.(encoding.TextUnmarshaler); ok {
|
||||||
// Special case. Look for a value satisfying the TextUnmarshaler interface.
|
|
||||||
if v, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
|
|
||||||
return md.unifyText(data, v)
|
return md.unifyText(data, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// The behavior here is incorrect whenever a Go type satisfies the
|
// The behavior here is incorrect whenever a Go type satisfies the
|
||||||
// encoding.TextUnmarshaler interface but also corresponds to a TOML hash or
|
// encoding.TextUnmarshaler interface but also corresponds to a TOML hash or
|
||||||
@ -218,7 +223,6 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
|||||||
|
|
||||||
k := rv.Kind()
|
k := rv.Kind()
|
||||||
|
|
||||||
// laziness
|
|
||||||
if k >= reflect.Int && k <= reflect.Uint64 {
|
if k >= reflect.Int && k <= reflect.Uint64 {
|
||||||
return md.unifyInt(data, rv)
|
return md.unifyInt(data, rv)
|
||||||
}
|
}
|
||||||
@ -244,15 +248,14 @@ func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
|||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return md.unifyBool(data, rv)
|
return md.unifyBool(data, rv)
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
// we only support empty interfaces.
|
if rv.NumMethod() > 0 { // Only support empty interfaces are supported.
|
||||||
if rv.NumMethod() > 0 {
|
return md.e("unsupported type %s", rv.Type())
|
||||||
return e("unsupported type %s", rv.Type())
|
|
||||||
}
|
}
|
||||||
return md.unifyAnything(data, rv)
|
return md.unifyAnything(data, rv)
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
return md.unifyFloat64(data, rv)
|
return md.unifyFloat64(data, rv)
|
||||||
}
|
}
|
||||||
return e("unsupported type %s", rv.Kind())
|
return md.e("unsupported type %s", rv.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
||||||
@ -261,7 +264,7 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
|||||||
if mapping == nil {
|
if mapping == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return e("type mismatch for %s: expected table but found %T",
|
return md.e("type mismatch for %s: expected table but found %T",
|
||||||
rv.Type().String(), mapping)
|
rv.Type().String(), mapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,13 +290,14 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
|||||||
if isUnifiable(subv) {
|
if isUnifiable(subv) {
|
||||||
md.decoded[md.context.add(key).String()] = struct{}{}
|
md.decoded[md.context.add(key).String()] = struct{}{}
|
||||||
md.context = append(md.context, key)
|
md.context = append(md.context, key)
|
||||||
|
|
||||||
err := md.unify(datum, subv)
|
err := md.unify(datum, subv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
md.context = md.context[0 : len(md.context)-1]
|
md.context = md.context[0 : len(md.context)-1]
|
||||||
} else if f.name != "" {
|
} else if f.name != "" {
|
||||||
return e("cannot write unexported field %s.%s", rv.Type().String(), f.name)
|
return md.e("cannot write unexported field %s.%s", rv.Type().String(), f.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,10 +305,10 @@ func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
|
||||||
if k := rv.Type().Key().Kind(); k != reflect.String {
|
keyType := rv.Type().Key().Kind()
|
||||||
return fmt.Errorf(
|
if keyType != reflect.String && keyType != reflect.Interface {
|
||||||
"toml: cannot decode to a map with non-string key type (%s in %q)",
|
return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)",
|
||||||
k, rv.Type())
|
keyType, rv.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
tmap, ok := mapping.(map[string]interface{})
|
tmap, ok := mapping.(map[string]interface{})
|
||||||
@ -322,13 +326,22 @@ func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
|
|||||||
md.context = append(md.context, k)
|
md.context = append(md.context, k)
|
||||||
|
|
||||||
rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
|
rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
|
||||||
if err := md.unify(v, rvval); err != nil {
|
|
||||||
|
err := md.unify(v, indirect(rvval))
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
md.context = md.context[0 : len(md.context)-1]
|
md.context = md.context[0 : len(md.context)-1]
|
||||||
|
|
||||||
rvkey := indirect(reflect.New(rv.Type().Key()))
|
rvkey := indirect(reflect.New(rv.Type().Key()))
|
||||||
rvkey.SetString(k)
|
|
||||||
|
switch keyType {
|
||||||
|
case reflect.Interface:
|
||||||
|
rvkey.Set(reflect.ValueOf(k))
|
||||||
|
case reflect.String:
|
||||||
|
rvkey.SetString(k)
|
||||||
|
}
|
||||||
|
|
||||||
rv.SetMapIndex(rvkey, rvval)
|
rv.SetMapIndex(rvkey, rvval)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -343,7 +356,7 @@ func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {
|
|||||||
return md.badtype("slice", data)
|
return md.badtype("slice", data)
|
||||||
}
|
}
|
||||||
if l := datav.Len(); l != rv.Len() {
|
if l := datav.Len(); l != rv.Len() {
|
||||||
return e("expected array length %d; got TOML array of length %d", rv.Len(), l)
|
return md.e("expected array length %d; got TOML array of length %d", rv.Len(), l)
|
||||||
}
|
}
|
||||||
return md.unifySliceArray(datav, rv)
|
return md.unifySliceArray(datav, rv)
|
||||||
}
|
}
|
||||||
@ -376,6 +389,18 @@ func (md *MetaData) unifySliceArray(data, rv reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
|
||||||
|
_, ok := rv.Interface().(json.Number)
|
||||||
|
if ok {
|
||||||
|
if i, ok := data.(int64); ok {
|
||||||
|
rv.SetString(strconv.FormatInt(i, 10))
|
||||||
|
} else if f, ok := data.(float64); ok {
|
||||||
|
rv.SetString(strconv.FormatFloat(f, 'f', -1, 64))
|
||||||
|
} else {
|
||||||
|
return md.badtype("string", data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if s, ok := data.(string); ok {
|
if s, ok := data.(string); ok {
|
||||||
rv.SetString(s)
|
rv.SetString(s)
|
||||||
return nil
|
return nil
|
||||||
@ -384,11 +409,13 @@ func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
||||||
|
rvk := rv.Kind()
|
||||||
|
|
||||||
if num, ok := data.(float64); ok {
|
if num, ok := data.(float64); ok {
|
||||||
switch rv.Kind() {
|
switch rvk {
|
||||||
case reflect.Float32:
|
case reflect.Float32:
|
||||||
if num < -math.MaxFloat32 || num > math.MaxFloat32 {
|
if num < -math.MaxFloat32 || num > math.MaxFloat32 {
|
||||||
return e("value %f is out of range for float32", num)
|
return md.parseErr(errParseRange{i: num, size: rvk.String()})
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case reflect.Float64:
|
case reflect.Float64:
|
||||||
@ -400,20 +427,11 @@ func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if num, ok := data.(int64); ok {
|
if num, ok := data.(int64); ok {
|
||||||
switch rv.Kind() {
|
if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) ||
|
||||||
case reflect.Float32:
|
(rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) {
|
||||||
if num < -maxSafeFloat32Int || num > maxSafeFloat32Int {
|
return md.parseErr(errParseRange{i: num, size: rvk.String()})
|
||||||
return e("value %d is out of range for float32", num)
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
case reflect.Float64:
|
|
||||||
if num < -maxSafeFloat64Int || num > maxSafeFloat64Int {
|
|
||||||
return e("value %d is out of range for float64", num)
|
|
||||||
}
|
|
||||||
rv.SetFloat(float64(num))
|
|
||||||
default:
|
|
||||||
panic("bug")
|
|
||||||
}
|
}
|
||||||
|
rv.SetFloat(float64(num))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,50 +439,46 @@ func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
|
||||||
if num, ok := data.(int64); ok {
|
_, ok := rv.Interface().(time.Duration)
|
||||||
if rv.Kind() >= reflect.Int && rv.Kind() <= reflect.Int64 {
|
if ok {
|
||||||
switch rv.Kind() {
|
// Parse as string duration, and fall back to regular integer parsing
|
||||||
case reflect.Int, reflect.Int64:
|
// (as nanosecond) if this is not a string.
|
||||||
// No bounds checking necessary.
|
if s, ok := data.(string); ok {
|
||||||
case reflect.Int8:
|
dur, err := time.ParseDuration(s)
|
||||||
if num < math.MinInt8 || num > math.MaxInt8 {
|
if err != nil {
|
||||||
return e("value %d is out of range for int8", num)
|
return md.parseErr(errParseDuration{s})
|
||||||
}
|
|
||||||
case reflect.Int16:
|
|
||||||
if num < math.MinInt16 || num > math.MaxInt16 {
|
|
||||||
return e("value %d is out of range for int16", num)
|
|
||||||
}
|
|
||||||
case reflect.Int32:
|
|
||||||
if num < math.MinInt32 || num > math.MaxInt32 {
|
|
||||||
return e("value %d is out of range for int32", num)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
rv.SetInt(num)
|
rv.SetInt(int64(dur))
|
||||||
} else if rv.Kind() >= reflect.Uint && rv.Kind() <= reflect.Uint64 {
|
return nil
|
||||||
unum := uint64(num)
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Uint, reflect.Uint64:
|
|
||||||
// No bounds checking necessary.
|
|
||||||
case reflect.Uint8:
|
|
||||||
if num < 0 || unum > math.MaxUint8 {
|
|
||||||
return e("value %d is out of range for uint8", num)
|
|
||||||
}
|
|
||||||
case reflect.Uint16:
|
|
||||||
if num < 0 || unum > math.MaxUint16 {
|
|
||||||
return e("value %d is out of range for uint16", num)
|
|
||||||
}
|
|
||||||
case reflect.Uint32:
|
|
||||||
if num < 0 || unum > math.MaxUint32 {
|
|
||||||
return e("value %d is out of range for uint32", num)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv.SetUint(unum)
|
|
||||||
} else {
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return md.badtype("integer", data)
|
|
||||||
|
num, ok := data.(int64)
|
||||||
|
if !ok {
|
||||||
|
return md.badtype("integer", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
rvk := rv.Kind()
|
||||||
|
switch {
|
||||||
|
case rvk >= reflect.Int && rvk <= reflect.Int64:
|
||||||
|
if (rvk == reflect.Int8 && (num < math.MinInt8 || num > math.MaxInt8)) ||
|
||||||
|
(rvk == reflect.Int16 && (num < math.MinInt16 || num > math.MaxInt16)) ||
|
||||||
|
(rvk == reflect.Int32 && (num < math.MinInt32 || num > math.MaxInt32)) {
|
||||||
|
return md.parseErr(errParseRange{i: num, size: rvk.String()})
|
||||||
|
}
|
||||||
|
rv.SetInt(num)
|
||||||
|
case rvk >= reflect.Uint && rvk <= reflect.Uint64:
|
||||||
|
unum := uint64(num)
|
||||||
|
if rvk == reflect.Uint8 && (num < 0 || unum > math.MaxUint8) ||
|
||||||
|
rvk == reflect.Uint16 && (num < 0 || unum > math.MaxUint16) ||
|
||||||
|
rvk == reflect.Uint32 && (num < 0 || unum > math.MaxUint32) {
|
||||||
|
return md.parseErr(errParseRange{i: num, size: rvk.String()})
|
||||||
|
}
|
||||||
|
rv.SetUint(unum)
|
||||||
|
default:
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
|
func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
|
||||||
@ -489,7 +503,7 @@ func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s = string(text)
|
s = string(text)
|
||||||
case TextMarshaler:
|
case encoding.TextMarshaler:
|
||||||
text, err := sdata.MarshalText()
|
text, err := sdata.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -515,7 +529,30 @@ func (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (md *MetaData) badtype(dst string, data interface{}) error {
|
func (md *MetaData) badtype(dst string, data interface{}) error {
|
||||||
return e("incompatible types: TOML key %q has type %T; destination has type %s", md.context, data, dst)
|
return md.e("incompatible types: TOML value has type %T; destination has type %s", data, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) parseErr(err error) error {
|
||||||
|
k := md.context.String()
|
||||||
|
return ParseError{
|
||||||
|
LastKey: k,
|
||||||
|
Position: md.keyInfo[k].pos,
|
||||||
|
Line: md.keyInfo[k].pos.Line,
|
||||||
|
err: err,
|
||||||
|
input: string(md.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) e(format string, args ...interface{}) error {
|
||||||
|
f := "toml: "
|
||||||
|
if len(md.context) > 0 {
|
||||||
|
f = fmt.Sprintf("toml: (last key %q): ", md.context)
|
||||||
|
p := md.keyInfo[md.context.String()].pos
|
||||||
|
if p.Line > 0 {
|
||||||
|
f = fmt.Sprintf("toml: line %d (last key %q): ", p.Line, md.context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf(f+format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// rvalue returns a reflect.Value of `v`. All pointers are resolved.
|
// rvalue returns a reflect.Value of `v`. All pointers are resolved.
|
||||||
@ -534,7 +571,11 @@ func indirect(v reflect.Value) reflect.Value {
|
|||||||
if v.Kind() != reflect.Ptr {
|
if v.Kind() != reflect.Ptr {
|
||||||
if v.CanSet() {
|
if v.CanSet() {
|
||||||
pv := v.Addr()
|
pv := v.Addr()
|
||||||
if _, ok := pv.Interface().(encoding.TextUnmarshaler); ok {
|
pvi := pv.Interface()
|
||||||
|
if _, ok := pvi.(encoding.TextUnmarshaler); ok {
|
||||||
|
return pv
|
||||||
|
}
|
||||||
|
if _, ok := pvi.(Unmarshaler); ok {
|
||||||
return pv
|
return pv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,12 +591,12 @@ func isUnifiable(rv reflect.Value) bool {
|
|||||||
if rv.CanSet() {
|
if rv.CanSet() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if _, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
|
rvi := rv.Interface()
|
||||||
|
if _, ok := rvi.(encoding.TextUnmarshaler); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := rvi.(Unmarshaler); ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func e(format string, args ...interface{}) error {
|
|
||||||
return fmt.Errorf("toml: "+format, args...)
|
|
||||||
}
|
|
||||||
|
208
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
208
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
@ -3,6 +3,7 @@ package toml
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -63,6 +64,12 @@ var dblQuotedReplacer = strings.NewReplacer(
|
|||||||
"\x7f", `\u007f`,
|
"\x7f", `\u007f`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
marshalToml = reflect.TypeOf((*Marshaler)(nil)).Elem()
|
||||||
|
marshalText = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
|
||||||
|
timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
||||||
|
)
|
||||||
|
|
||||||
// Marshaler is the interface implemented by types that can marshal themselves
|
// Marshaler is the interface implemented by types that can marshal themselves
|
||||||
// into valid TOML.
|
// into valid TOML.
|
||||||
type Marshaler interface {
|
type Marshaler interface {
|
||||||
@ -74,6 +81,9 @@ type Marshaler interface {
|
|||||||
// The mapping between Go values and TOML values should be precisely the same as
|
// The mapping between Go values and TOML values should be precisely the same as
|
||||||
// for the Decode* functions.
|
// for the Decode* functions.
|
||||||
//
|
//
|
||||||
|
// time.Time is encoded as a RFC 3339 string, and time.Duration as its string
|
||||||
|
// representation.
|
||||||
|
//
|
||||||
// The toml.Marshaler and encoder.TextMarshaler interfaces are supported to
|
// The toml.Marshaler and encoder.TextMarshaler interfaces are supported to
|
||||||
// encoding the value as custom TOML.
|
// encoding the value as custom TOML.
|
||||||
//
|
//
|
||||||
@ -85,6 +95,17 @@ type Marshaler interface {
|
|||||||
//
|
//
|
||||||
// Go maps will be sorted alphabetically by key for deterministic output.
|
// Go maps will be sorted alphabetically by key for deterministic output.
|
||||||
//
|
//
|
||||||
|
// The toml struct tag can be used to provide the key name; if omitted the
|
||||||
|
// struct field name will be used. If the "omitempty" option is present the
|
||||||
|
// following value will be skipped:
|
||||||
|
//
|
||||||
|
// - arrays, slices, maps, and string with len of 0
|
||||||
|
// - struct with all zero values
|
||||||
|
// - bool false
|
||||||
|
//
|
||||||
|
// If omitzero is given all int and float types with a value of 0 will be
|
||||||
|
// skipped.
|
||||||
|
//
|
||||||
// Encoding Go values without a corresponding TOML representation will return an
|
// Encoding Go values without a corresponding TOML representation will return an
|
||||||
// error. Examples of this includes maps with non-string keys, slices with nil
|
// error. Examples of this includes maps with non-string keys, slices with nil
|
||||||
// elements, embedded non-struct types, and nested slices containing maps or
|
// elements, embedded non-struct types, and nested slices containing maps or
|
||||||
@ -136,18 +157,15 @@ func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *Encoder) encode(key Key, rv reflect.Value) {
|
func (enc *Encoder) encode(key Key, rv reflect.Value) {
|
||||||
// Special case: time needs to be in ISO8601 format.
|
// If we can marshal the type to text, then we use that. This prevents the
|
||||||
//
|
// encoder for handling these types as generic structs (or whatever the
|
||||||
// Special case: if we can marshal the type to text, then we used that. This
|
// underlying type of a TextMarshaler is).
|
||||||
// prevents the encoder for handling these types as generic structs (or
|
switch {
|
||||||
// whatever the underlying type of a TextMarshaler is).
|
case isMarshaler(rv):
|
||||||
switch t := rv.Interface().(type) {
|
|
||||||
case time.Time, encoding.TextMarshaler, Marshaler:
|
|
||||||
enc.writeKeyValue(key, rv, false)
|
enc.writeKeyValue(key, rv, false)
|
||||||
return
|
return
|
||||||
// TODO: #76 would make this superfluous after implemented.
|
case rv.Type() == primitiveType: // TODO: #76 would make this superfluous after implemented.
|
||||||
case Primitive:
|
enc.encode(key, reflect.ValueOf(rv.Interface().(Primitive).undecoded))
|
||||||
enc.encode(key, reflect.ValueOf(t.undecoded))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +230,9 @@ func (enc *Encoder) eElement(rv reflect.Value) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
encPanic(err)
|
encPanic(err)
|
||||||
}
|
}
|
||||||
|
if s == nil {
|
||||||
|
encPanic(errors.New("MarshalTOML returned nil and no error"))
|
||||||
|
}
|
||||||
enc.w.Write(s)
|
enc.w.Write(s)
|
||||||
return
|
return
|
||||||
case encoding.TextMarshaler:
|
case encoding.TextMarshaler:
|
||||||
@ -219,11 +240,34 @@ func (enc *Encoder) eElement(rv reflect.Value) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
encPanic(err)
|
encPanic(err)
|
||||||
}
|
}
|
||||||
|
if s == nil {
|
||||||
|
encPanic(errors.New("MarshalText returned nil and no error"))
|
||||||
|
}
|
||||||
enc.writeQuoted(string(s))
|
enc.writeQuoted(string(s))
|
||||||
return
|
return
|
||||||
|
case time.Duration:
|
||||||
|
enc.writeQuoted(v.String())
|
||||||
|
return
|
||||||
|
case json.Number:
|
||||||
|
n, _ := rv.Interface().(json.Number)
|
||||||
|
|
||||||
|
if n == "" { /// Useful zero value.
|
||||||
|
enc.w.WriteByte('0')
|
||||||
|
return
|
||||||
|
} else if v, err := n.Int64(); err == nil {
|
||||||
|
enc.eElement(reflect.ValueOf(v))
|
||||||
|
return
|
||||||
|
} else if v, err := n.Float64(); err == nil {
|
||||||
|
enc.eElement(reflect.ValueOf(v))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
encPanic(errors.New(fmt.Sprintf("Unable to convert \"%s\" to neither int64 nor float64", n)))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch rv.Kind() {
|
switch rv.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
enc.eElement(rv.Elem())
|
||||||
|
return
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
enc.writeQuoted(rv.String())
|
enc.writeQuoted(rv.String())
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
@ -259,7 +303,7 @@ func (enc *Encoder) eElement(rv reflect.Value) {
|
|||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
enc.eElement(rv.Elem())
|
enc.eElement(rv.Elem())
|
||||||
default:
|
default:
|
||||||
encPanic(fmt.Errorf("unexpected primitive type: %T", rv.Interface()))
|
encPanic(fmt.Errorf("unexpected type: %T", rv.Interface()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +324,7 @@ func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) {
|
|||||||
length := rv.Len()
|
length := rv.Len()
|
||||||
enc.wf("[")
|
enc.wf("[")
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
elem := rv.Index(i)
|
elem := eindirect(rv.Index(i))
|
||||||
enc.eElement(elem)
|
enc.eElement(elem)
|
||||||
if i != length-1 {
|
if i != length-1 {
|
||||||
enc.wf(", ")
|
enc.wf(", ")
|
||||||
@ -294,7 +338,7 @@ func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) {
|
|||||||
encPanic(errNoKey)
|
encPanic(errNoKey)
|
||||||
}
|
}
|
||||||
for i := 0; i < rv.Len(); i++ {
|
for i := 0; i < rv.Len(); i++ {
|
||||||
trv := rv.Index(i)
|
trv := eindirect(rv.Index(i))
|
||||||
if isNil(trv) {
|
if isNil(trv) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -319,7 +363,7 @@ func (enc *Encoder) eTable(key Key, rv reflect.Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) {
|
func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) {
|
||||||
switch rv := eindirect(rv); rv.Kind() {
|
switch rv.Kind() {
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
enc.eMap(key, rv, inline)
|
enc.eMap(key, rv, inline)
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
@ -341,7 +385,7 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
|
|||||||
var mapKeysDirect, mapKeysSub []string
|
var mapKeysDirect, mapKeysSub []string
|
||||||
for _, mapKey := range rv.MapKeys() {
|
for _, mapKey := range rv.MapKeys() {
|
||||||
k := mapKey.String()
|
k := mapKey.String()
|
||||||
if typeIsTable(tomlTypeOfGo(rv.MapIndex(mapKey))) {
|
if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) {
|
||||||
mapKeysSub = append(mapKeysSub, k)
|
mapKeysSub = append(mapKeysSub, k)
|
||||||
} else {
|
} else {
|
||||||
mapKeysDirect = append(mapKeysDirect, k)
|
mapKeysDirect = append(mapKeysDirect, k)
|
||||||
@ -351,7 +395,7 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
|
|||||||
var writeMapKeys = func(mapKeys []string, trailC bool) {
|
var writeMapKeys = func(mapKeys []string, trailC bool) {
|
||||||
sort.Strings(mapKeys)
|
sort.Strings(mapKeys)
|
||||||
for i, mapKey := range mapKeys {
|
for i, mapKey := range mapKeys {
|
||||||
val := rv.MapIndex(reflect.ValueOf(mapKey))
|
val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey)))
|
||||||
if isNil(val) {
|
if isNil(val) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -379,6 +423,13 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
|
|||||||
|
|
||||||
const is32Bit = (32 << (^uint(0) >> 63)) == 32
|
const is32Bit = (32 << (^uint(0) >> 63)) == 32
|
||||||
|
|
||||||
|
func pointerTo(t reflect.Type) reflect.Type {
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
return pointerTo(t.Elem())
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
||||||
// Write keys for fields directly under this key first, because if we write
|
// Write keys for fields directly under this key first, because if we write
|
||||||
// a field that creates a new table then all keys under it will be in that
|
// a field that creates a new table then all keys under it will be in that
|
||||||
@ -395,7 +446,8 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
|||||||
addFields = func(rt reflect.Type, rv reflect.Value, start []int) {
|
addFields = func(rt reflect.Type, rv reflect.Value, start []int) {
|
||||||
for i := 0; i < rt.NumField(); i++ {
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
f := rt.Field(i)
|
f := rt.Field(i)
|
||||||
if f.PkgPath != "" && !f.Anonymous { /// Skip unexported fields.
|
isEmbed := f.Anonymous && pointerTo(f.Type).Kind() == reflect.Struct
|
||||||
|
if f.PkgPath != "" && !isEmbed { /// Skip unexported fields.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
opts := getOptions(f.Tag)
|
opts := getOptions(f.Tag)
|
||||||
@ -403,27 +455,16 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
frv := rv.Field(i)
|
frv := eindirect(rv.Field(i))
|
||||||
|
|
||||||
// Treat anonymous struct fields with tag names as though they are
|
// Treat anonymous struct fields with tag names as though they are
|
||||||
// not anonymous, like encoding/json does.
|
// not anonymous, like encoding/json does.
|
||||||
//
|
//
|
||||||
// Non-struct anonymous fields use the normal encoding logic.
|
// Non-struct anonymous fields use the normal encoding logic.
|
||||||
if f.Anonymous {
|
if isEmbed {
|
||||||
t := f.Type
|
if getOptions(f.Tag).name == "" && frv.Kind() == reflect.Struct {
|
||||||
switch t.Kind() {
|
addFields(frv.Type(), frv, append(start, f.Index...))
|
||||||
case reflect.Struct:
|
continue
|
||||||
if getOptions(f.Tag).name == "" {
|
|
||||||
addFields(t, frv, append(start, f.Index...))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case reflect.Ptr:
|
|
||||||
if t.Elem().Kind() == reflect.Struct && getOptions(f.Tag).name == "" {
|
|
||||||
if !frv.IsNil() {
|
|
||||||
addFields(t.Elem(), frv.Elem(), append(start, f.Index...))
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +490,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
|||||||
writeFields := func(fields [][]int) {
|
writeFields := func(fields [][]int) {
|
||||||
for _, fieldIndex := range fields {
|
for _, fieldIndex := range fields {
|
||||||
fieldType := rt.FieldByIndex(fieldIndex)
|
fieldType := rt.FieldByIndex(fieldIndex)
|
||||||
fieldVal := rv.FieldByIndex(fieldIndex)
|
fieldVal := eindirect(rv.FieldByIndex(fieldIndex))
|
||||||
|
|
||||||
if isNil(fieldVal) { /// Don't write anything for nil fields.
|
if isNil(fieldVal) { /// Don't write anything for nil fields.
|
||||||
continue
|
continue
|
||||||
@ -502,6 +543,21 @@ func tomlTypeOfGo(rv reflect.Value) tomlType {
|
|||||||
if isNil(rv) || !rv.IsValid() {
|
if isNil(rv) || !rv.IsValid() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rv.Kind() == reflect.Struct {
|
||||||
|
if rv.Type() == timeType {
|
||||||
|
return tomlDatetime
|
||||||
|
}
|
||||||
|
if isMarshaler(rv) {
|
||||||
|
return tomlString
|
||||||
|
}
|
||||||
|
return tomlHash
|
||||||
|
}
|
||||||
|
|
||||||
|
if isMarshaler(rv) {
|
||||||
|
return tomlString
|
||||||
|
}
|
||||||
|
|
||||||
switch rv.Kind() {
|
switch rv.Kind() {
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return tomlBool
|
return tomlBool
|
||||||
@ -513,7 +569,7 @@ func tomlTypeOfGo(rv reflect.Value) tomlType {
|
|||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
return tomlFloat
|
return tomlFloat
|
||||||
case reflect.Array, reflect.Slice:
|
case reflect.Array, reflect.Slice:
|
||||||
if typeEqual(tomlHash, tomlArrayType(rv)) {
|
if isTableArray(rv) {
|
||||||
return tomlArrayHash
|
return tomlArrayHash
|
||||||
}
|
}
|
||||||
return tomlArray
|
return tomlArray
|
||||||
@ -523,67 +579,35 @@ func tomlTypeOfGo(rv reflect.Value) tomlType {
|
|||||||
return tomlString
|
return tomlString
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
return tomlHash
|
return tomlHash
|
||||||
case reflect.Struct:
|
|
||||||
if _, ok := rv.Interface().(time.Time); ok {
|
|
||||||
return tomlDatetime
|
|
||||||
}
|
|
||||||
if isMarshaler(rv) {
|
|
||||||
return tomlString
|
|
||||||
}
|
|
||||||
return tomlHash
|
|
||||||
default:
|
default:
|
||||||
if isMarshaler(rv) {
|
|
||||||
return tomlString
|
|
||||||
}
|
|
||||||
|
|
||||||
encPanic(errors.New("unsupported type: " + rv.Kind().String()))
|
encPanic(errors.New("unsupported type: " + rv.Kind().String()))
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isMarshaler(rv reflect.Value) bool {
|
func isMarshaler(rv reflect.Value) bool {
|
||||||
switch rv.Interface().(type) {
|
return rv.Type().Implements(marshalText) || rv.Type().Implements(marshalToml)
|
||||||
case encoding.TextMarshaler:
|
|
||||||
return true
|
|
||||||
case Marshaler:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Someone used a pointer receiver: we can make it work for pointer values.
|
|
||||||
if rv.CanAddr() {
|
|
||||||
if _, ok := rv.Addr().Interface().(encoding.TextMarshaler); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if _, ok := rv.Addr().Interface().(Marshaler); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tomlArrayType returns the element type of a TOML array. The type returned
|
// isTableArray reports if all entries in the array or slice are a table.
|
||||||
// may be nil if it cannot be determined (e.g., a nil slice or a zero length
|
func isTableArray(arr reflect.Value) bool {
|
||||||
// slize). This function may also panic if it finds a type that cannot be
|
if isNil(arr) || !arr.IsValid() || arr.Len() == 0 {
|
||||||
// expressed in TOML (such as nil elements, heterogeneous arrays or directly
|
return false
|
||||||
// nested arrays of tables).
|
|
||||||
func tomlArrayType(rv reflect.Value) tomlType {
|
|
||||||
if isNil(rv) || !rv.IsValid() || rv.Len() == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Don't allow nil.
|
ret := true
|
||||||
rvlen := rv.Len()
|
for i := 0; i < arr.Len(); i++ {
|
||||||
for i := 1; i < rvlen; i++ {
|
tt := tomlTypeOfGo(eindirect(arr.Index(i)))
|
||||||
if tomlTypeOfGo(rv.Index(i)) == nil {
|
// Don't allow nil.
|
||||||
|
if tt == nil {
|
||||||
encPanic(errArrayNilElement)
|
encPanic(errArrayNilElement)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
firstType := tomlTypeOfGo(rv.Index(0))
|
if ret && !typeEqual(tomlHash, tt) {
|
||||||
if firstType == nil {
|
ret = false
|
||||||
encPanic(errArrayNilElement)
|
}
|
||||||
}
|
}
|
||||||
return firstType
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
type tagOptions struct {
|
type tagOptions struct {
|
||||||
@ -628,6 +652,8 @@ func isEmpty(rv reflect.Value) bool {
|
|||||||
switch rv.Kind() {
|
switch rv.Kind() {
|
||||||
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
|
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
|
||||||
return rv.Len() == 0
|
return rv.Len() == 0
|
||||||
|
case reflect.Struct:
|
||||||
|
return reflect.Zero(rv.Type()).Interface() == rv.Interface()
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return !rv.Bool()
|
return !rv.Bool()
|
||||||
}
|
}
|
||||||
@ -679,13 +705,25 @@ func encPanic(err error) {
|
|||||||
panic(tomlEncodeError{err})
|
panic(tomlEncodeError{err})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve any level of pointers to the actual value (e.g. **string → string).
|
||||||
func eindirect(v reflect.Value) reflect.Value {
|
func eindirect(v reflect.Value) reflect.Value {
|
||||||
switch v.Kind() {
|
if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface {
|
||||||
case reflect.Ptr, reflect.Interface:
|
if isMarshaler(v) {
|
||||||
return eindirect(v.Elem())
|
return v
|
||||||
default:
|
}
|
||||||
|
if v.CanAddr() { /// Special case for marshalers; see #358.
|
||||||
|
if pv := v.Addr(); isMarshaler(pv) {
|
||||||
|
return pv
|
||||||
|
}
|
||||||
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.IsNil() {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
return eindirect(v.Elem())
|
||||||
}
|
}
|
||||||
|
|
||||||
func isNil(rv reflect.Value) bool {
|
func isNil(rv reflect.Value) bool {
|
||||||
|
53
vendor/github.com/BurntSushi/toml/error.go
generated
vendored
53
vendor/github.com/BurntSushi/toml/error.go
generated
vendored
@ -128,9 +128,13 @@ func (pe ParseError) ErrorWithPosition() string {
|
|||||||
func (pe ParseError) ErrorWithUsage() string {
|
func (pe ParseError) ErrorWithUsage() string {
|
||||||
m := pe.ErrorWithPosition()
|
m := pe.ErrorWithPosition()
|
||||||
if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" {
|
if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" {
|
||||||
return m + "Error help:\n\n " +
|
lines := strings.Split(strings.TrimSpace(u.Usage()), "\n")
|
||||||
strings.ReplaceAll(strings.TrimSpace(u.Usage()), "\n", "\n ") +
|
for i := range lines {
|
||||||
"\n"
|
if lines[i] != "" {
|
||||||
|
lines[i] = " " + lines[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m + "Error help:\n\n" + strings.Join(lines, "\n") + "\n"
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
@ -160,6 +164,11 @@ type (
|
|||||||
errLexInvalidDate struct{ v string }
|
errLexInvalidDate struct{ v string }
|
||||||
errLexInlineTableNL struct{}
|
errLexInlineTableNL struct{}
|
||||||
errLexStringNL struct{}
|
errLexStringNL struct{}
|
||||||
|
errParseRange struct {
|
||||||
|
i interface{} // int or float
|
||||||
|
size string // "int64", "uint16", etc.
|
||||||
|
}
|
||||||
|
errParseDuration struct{ d string }
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e errLexControl) Error() string {
|
func (e errLexControl) Error() string {
|
||||||
@ -179,6 +188,10 @@ func (e errLexInlineTableNL) Error() string { return "newlines not allowed withi
|
|||||||
func (e errLexInlineTableNL) Usage() string { return usageInlineNewline }
|
func (e errLexInlineTableNL) Usage() string { return usageInlineNewline }
|
||||||
func (e errLexStringNL) Error() string { return "strings cannot contain newlines" }
|
func (e errLexStringNL) Error() string { return "strings cannot contain newlines" }
|
||||||
func (e errLexStringNL) Usage() string { return usageStringNewline }
|
func (e errLexStringNL) Usage() string { return usageStringNewline }
|
||||||
|
func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) }
|
||||||
|
func (e errParseRange) Usage() string { return usageIntOverflow }
|
||||||
|
func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) }
|
||||||
|
func (e errParseDuration) Usage() string { return usageDuration }
|
||||||
|
|
||||||
const usageEscape = `
|
const usageEscape = `
|
||||||
A '\' inside a "-delimited string is interpreted as an escape character.
|
A '\' inside a "-delimited string is interpreted as an escape character.
|
||||||
@ -227,3 +240,37 @@ Instead use """ or ''' to split strings over multiple lines:
|
|||||||
string = """Hello,
|
string = """Hello,
|
||||||
world!"""
|
world!"""
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const usageIntOverflow = `
|
||||||
|
This number is too large; this may be an error in the TOML, but it can also be a
|
||||||
|
bug in the program that uses too small of an integer.
|
||||||
|
|
||||||
|
The maximum and minimum values are:
|
||||||
|
|
||||||
|
size │ lowest │ highest
|
||||||
|
───────┼────────────────┼──────────
|
||||||
|
int8 │ -128 │ 127
|
||||||
|
int16 │ -32,768 │ 32,767
|
||||||
|
int32 │ -2,147,483,648 │ 2,147,483,647
|
||||||
|
int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
|
||||||
|
uint8 │ 0 │ 255
|
||||||
|
uint16 │ 0 │ 65535
|
||||||
|
uint32 │ 0 │ 4294967295
|
||||||
|
uint64 │ 0 │ 1.8 × 10¹⁸
|
||||||
|
|
||||||
|
int refers to int32 on 32-bit systems and int64 on 64-bit systems.
|
||||||
|
`
|
||||||
|
|
||||||
|
const usageDuration = `
|
||||||
|
A duration must be as "number<unit>", without any spaces. Valid units are:
|
||||||
|
|
||||||
|
ns nanoseconds (billionth of a second)
|
||||||
|
us, µs microseconds (millionth of a second)
|
||||||
|
ms milliseconds (thousands of a second)
|
||||||
|
s seconds
|
||||||
|
m minutes
|
||||||
|
h hours
|
||||||
|
|
||||||
|
You can combine multiple units; for example "5m10s" for 5 minutes and 10
|
||||||
|
seconds.
|
||||||
|
`
|
||||||
|
17
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
17
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
@ -82,7 +82,7 @@ func (lx *lexer) nextItem() item {
|
|||||||
return item
|
return item
|
||||||
default:
|
default:
|
||||||
lx.state = lx.state(lx)
|
lx.state = lx.state(lx)
|
||||||
//fmt.Printf(" STATE %-24s current: %-10q stack: %s\n", lx.state, lx.current(), lx.stack)
|
//fmt.Printf(" STATE %-24s current: %-10s stack: %s\n", lx.state, lx.current(), lx.stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -716,7 +716,17 @@ func lexMultilineString(lx *lexer) stateFn {
|
|||||||
if lx.peek() == '"' {
|
if lx.peek() == '"' {
|
||||||
/// Check if we already lexed 5 's; if so we have 6 now, and
|
/// Check if we already lexed 5 's; if so we have 6 now, and
|
||||||
/// that's just too many man!
|
/// that's just too many man!
|
||||||
if strings.HasSuffix(lx.current(), `"""""`) {
|
///
|
||||||
|
/// Second check is for the edge case:
|
||||||
|
///
|
||||||
|
/// two quotes allowed.
|
||||||
|
/// vv
|
||||||
|
/// """lol \""""""
|
||||||
|
/// ^^ ^^^---- closing three
|
||||||
|
/// escaped
|
||||||
|
///
|
||||||
|
/// But ugly, but it works
|
||||||
|
if strings.HasSuffix(lx.current(), `"""""`) && !strings.HasSuffix(lx.current(), `\"""""`) {
|
||||||
return lx.errorf(`unexpected '""""""'`)
|
return lx.errorf(`unexpected '""""""'`)
|
||||||
}
|
}
|
||||||
lx.backup()
|
lx.backup()
|
||||||
@ -807,8 +817,7 @@ func lexMultilineRawString(lx *lexer) stateFn {
|
|||||||
// lexMultilineStringEscape consumes an escaped character. It assumes that the
|
// lexMultilineStringEscape consumes an escaped character. It assumes that the
|
||||||
// preceding '\\' has already been consumed.
|
// preceding '\\' has already been consumed.
|
||||||
func lexMultilineStringEscape(lx *lexer) stateFn {
|
func lexMultilineStringEscape(lx *lexer) stateFn {
|
||||||
// Handle the special case first:
|
if isNL(lx.next()) { /// \ escaping newline.
|
||||||
if isNL(lx.next()) {
|
|
||||||
return lexMultilineString
|
return lexMultilineString
|
||||||
}
|
}
|
||||||
lx.backup()
|
lx.backup()
|
||||||
|
7
vendor/github.com/BurntSushi/toml/meta.go
generated
vendored
7
vendor/github.com/BurntSushi/toml/meta.go
generated
vendored
@ -12,10 +12,11 @@ import (
|
|||||||
type MetaData struct {
|
type MetaData struct {
|
||||||
context Key // Used only during decoding.
|
context Key // Used only during decoding.
|
||||||
|
|
||||||
|
keyInfo map[string]keyInfo
|
||||||
mapping map[string]interface{}
|
mapping map[string]interface{}
|
||||||
types map[string]tomlType
|
|
||||||
keys []Key
|
keys []Key
|
||||||
decoded map[string]struct{}
|
decoded map[string]struct{}
|
||||||
|
data []byte // Input file; for errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDefined reports if the key exists in the TOML data.
|
// IsDefined reports if the key exists in the TOML data.
|
||||||
@ -50,8 +51,8 @@ func (md *MetaData) IsDefined(key ...string) bool {
|
|||||||
// Type will return the empty string if given an empty key or a key that does
|
// Type will return the empty string if given an empty key or a key that does
|
||||||
// not exist. Keys are case sensitive.
|
// not exist. Keys are case sensitive.
|
||||||
func (md *MetaData) Type(key ...string) string {
|
func (md *MetaData) Type(key ...string) string {
|
||||||
if typ, ok := md.types[Key(key).String()]; ok {
|
if ki, ok := md.keyInfo[Key(key).String()]; ok {
|
||||||
return typ.typeString()
|
return ki.tomlType.typeString()
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
54
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
54
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
@ -16,12 +16,18 @@ type parser struct {
|
|||||||
currentKey string // Base key name for everything except hashes.
|
currentKey string // Base key name for everything except hashes.
|
||||||
pos Position // Current position in the TOML file.
|
pos Position // Current position in the TOML file.
|
||||||
|
|
||||||
ordered []Key // List of keys in the order that they appear in the TOML data.
|
ordered []Key // List of keys in the order that they appear in the TOML data.
|
||||||
|
|
||||||
|
keyInfo map[string]keyInfo // Map keyname → info about the TOML key.
|
||||||
mapping map[string]interface{} // Map keyname → key value.
|
mapping map[string]interface{} // Map keyname → key value.
|
||||||
types map[string]tomlType // Map keyname → TOML type.
|
|
||||||
implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names").
|
implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names").
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type keyInfo struct {
|
||||||
|
pos Position
|
||||||
|
tomlType tomlType
|
||||||
|
}
|
||||||
|
|
||||||
func parse(data string) (p *parser, err error) {
|
func parse(data string) (p *parser, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
@ -57,8 +63,8 @@ func parse(data string) (p *parser, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p = &parser{
|
p = &parser{
|
||||||
|
keyInfo: make(map[string]keyInfo),
|
||||||
mapping: make(map[string]interface{}),
|
mapping: make(map[string]interface{}),
|
||||||
types: make(map[string]tomlType),
|
|
||||||
lx: lex(data),
|
lx: lex(data),
|
||||||
ordered: make([]Key, 0),
|
ordered: make([]Key, 0),
|
||||||
implicits: make(map[string]struct{}),
|
implicits: make(map[string]struct{}),
|
||||||
@ -74,6 +80,15 @@ func parse(data string) (p *parser, err error) {
|
|||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *parser) panicErr(it item, err error) {
|
||||||
|
panic(ParseError{
|
||||||
|
err: err,
|
||||||
|
Position: it.pos,
|
||||||
|
Line: it.pos.Len,
|
||||||
|
LastKey: p.current(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (p *parser) panicItemf(it item, format string, v ...interface{}) {
|
func (p *parser) panicItemf(it item, format string, v ...interface{}) {
|
||||||
panic(ParseError{
|
panic(ParseError{
|
||||||
Message: fmt.Sprintf(format, v...),
|
Message: fmt.Sprintf(format, v...),
|
||||||
@ -94,7 +109,7 @@ func (p *parser) panicf(format string, v ...interface{}) {
|
|||||||
|
|
||||||
func (p *parser) next() item {
|
func (p *parser) next() item {
|
||||||
it := p.lx.nextItem()
|
it := p.lx.nextItem()
|
||||||
//fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.line, it.val)
|
//fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.pos.Line, it.val)
|
||||||
if it.typ == itemError {
|
if it.typ == itemError {
|
||||||
if it.err != nil {
|
if it.err != nil {
|
||||||
panic(ParseError{
|
panic(ParseError{
|
||||||
@ -146,7 +161,7 @@ func (p *parser) topLevel(item item) {
|
|||||||
p.assertEqual(itemTableEnd, name.typ)
|
p.assertEqual(itemTableEnd, name.typ)
|
||||||
|
|
||||||
p.addContext(key, false)
|
p.addContext(key, false)
|
||||||
p.setType("", tomlHash)
|
p.setType("", tomlHash, item.pos)
|
||||||
p.ordered = append(p.ordered, key)
|
p.ordered = append(p.ordered, key)
|
||||||
case itemArrayTableStart: // [[ .. ]]
|
case itemArrayTableStart: // [[ .. ]]
|
||||||
name := p.nextPos()
|
name := p.nextPos()
|
||||||
@ -158,7 +173,7 @@ func (p *parser) topLevel(item item) {
|
|||||||
p.assertEqual(itemArrayTableEnd, name.typ)
|
p.assertEqual(itemArrayTableEnd, name.typ)
|
||||||
|
|
||||||
p.addContext(key, true)
|
p.addContext(key, true)
|
||||||
p.setType("", tomlArrayHash)
|
p.setType("", tomlArrayHash, item.pos)
|
||||||
p.ordered = append(p.ordered, key)
|
p.ordered = append(p.ordered, key)
|
||||||
case itemKeyStart: // key = ..
|
case itemKeyStart: // key = ..
|
||||||
outerContext := p.context
|
outerContext := p.context
|
||||||
@ -181,8 +196,9 @@ func (p *parser) topLevel(item item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set value.
|
/// Set value.
|
||||||
val, typ := p.value(p.next(), false)
|
vItem := p.next()
|
||||||
p.set(p.currentKey, val, typ)
|
val, typ := p.value(vItem, false)
|
||||||
|
p.set(p.currentKey, val, typ, vItem.pos)
|
||||||
p.ordered = append(p.ordered, p.context.add(p.currentKey))
|
p.ordered = append(p.ordered, p.context.add(p.currentKey))
|
||||||
|
|
||||||
/// Remove the context we added (preserving any context from [tbl] lines).
|
/// Remove the context we added (preserving any context from [tbl] lines).
|
||||||
@ -266,7 +282,7 @@ func (p *parser) valueInteger(it item) (interface{}, tomlType) {
|
|||||||
// So mark the former as a bug but the latter as a legitimate user
|
// So mark the former as a bug but the latter as a legitimate user
|
||||||
// error.
|
// error.
|
||||||
if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
|
if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
|
||||||
p.panicItemf(it, "Integer '%s' is out of the range of 64-bit signed integers.", it.val)
|
p.panicErr(it, errParseRange{i: it.val, size: "int64"})
|
||||||
} else {
|
} else {
|
||||||
p.bug("Expected integer value, but got '%s'.", it.val)
|
p.bug("Expected integer value, but got '%s'.", it.val)
|
||||||
}
|
}
|
||||||
@ -304,7 +320,7 @@ func (p *parser) valueFloat(it item) (interface{}, tomlType) {
|
|||||||
num, err := strconv.ParseFloat(val, 64)
|
num, err := strconv.ParseFloat(val, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
|
if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
|
||||||
p.panicItemf(it, "Float '%s' is out of the range of 64-bit IEEE-754 floating-point numbers.", it.val)
|
p.panicErr(it, errParseRange{i: it.val, size: "float64"})
|
||||||
} else {
|
} else {
|
||||||
p.panicItemf(it, "Invalid float value: %q", it.val)
|
p.panicItemf(it, "Invalid float value: %q", it.val)
|
||||||
}
|
}
|
||||||
@ -343,9 +359,8 @@ func (p *parser) valueDatetime(it item) (interface{}, tomlType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) valueArray(it item) (interface{}, tomlType) {
|
func (p *parser) valueArray(it item) (interface{}, tomlType) {
|
||||||
p.setType(p.currentKey, tomlArray)
|
p.setType(p.currentKey, tomlArray, it.pos)
|
||||||
|
|
||||||
// p.setType(p.currentKey, typ)
|
|
||||||
var (
|
var (
|
||||||
types []tomlType
|
types []tomlType
|
||||||
|
|
||||||
@ -414,7 +429,7 @@ func (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tom
|
|||||||
|
|
||||||
/// Set the value.
|
/// Set the value.
|
||||||
val, typ := p.value(p.next(), false)
|
val, typ := p.value(p.next(), false)
|
||||||
p.set(p.currentKey, val, typ)
|
p.set(p.currentKey, val, typ, it.pos)
|
||||||
p.ordered = append(p.ordered, p.context.add(p.currentKey))
|
p.ordered = append(p.ordered, p.context.add(p.currentKey))
|
||||||
hash[p.currentKey] = val
|
hash[p.currentKey] = val
|
||||||
|
|
||||||
@ -533,9 +548,10 @@ func (p *parser) addContext(key Key, array bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set calls setValue and setType.
|
// set calls setValue and setType.
|
||||||
func (p *parser) set(key string, val interface{}, typ tomlType) {
|
func (p *parser) set(key string, val interface{}, typ tomlType, pos Position) {
|
||||||
p.setValue(key, val)
|
p.setValue(key, val)
|
||||||
p.setType(key, typ)
|
p.setType(key, typ, pos)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setValue sets the given key to the given value in the current context.
|
// setValue sets the given key to the given value in the current context.
|
||||||
@ -599,7 +615,7 @@ func (p *parser) setValue(key string, value interface{}) {
|
|||||||
//
|
//
|
||||||
// Note that if `key` is empty, then the type given will be applied to the
|
// Note that if `key` is empty, then the type given will be applied to the
|
||||||
// current context (which is either a table or an array of tables).
|
// current context (which is either a table or an array of tables).
|
||||||
func (p *parser) setType(key string, typ tomlType) {
|
func (p *parser) setType(key string, typ tomlType, pos Position) {
|
||||||
keyContext := make(Key, 0, len(p.context)+1)
|
keyContext := make(Key, 0, len(p.context)+1)
|
||||||
keyContext = append(keyContext, p.context...)
|
keyContext = append(keyContext, p.context...)
|
||||||
if len(key) > 0 { // allow type setting for hashes
|
if len(key) > 0 { // allow type setting for hashes
|
||||||
@ -611,7 +627,7 @@ func (p *parser) setType(key string, typ tomlType) {
|
|||||||
if len(keyContext) == 0 {
|
if len(keyContext) == 0 {
|
||||||
keyContext = Key{""}
|
keyContext = Key{""}
|
||||||
}
|
}
|
||||||
p.types[keyContext.String()] = typ
|
p.keyInfo[keyContext.String()] = keyInfo{tomlType: typ, pos: pos}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and
|
// Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and
|
||||||
@ -619,7 +635,7 @@ func (p *parser) setType(key string, typ tomlType) {
|
|||||||
func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} }
|
func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} }
|
||||||
func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) }
|
func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) }
|
||||||
func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok }
|
func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok }
|
||||||
func (p *parser) isArray(key Key) bool { return p.types[key.String()] == tomlArray }
|
func (p *parser) isArray(key Key) bool { return p.keyInfo[key.String()].tomlType == tomlArray }
|
||||||
func (p *parser) addImplicitContext(key Key) {
|
func (p *parser) addImplicitContext(key Key) {
|
||||||
p.addImplicit(key)
|
p.addImplicit(key)
|
||||||
p.addContext(key, false)
|
p.addContext(key, false)
|
||||||
@ -710,10 +726,8 @@ func (p *parser) replaceEscapes(it item, str string) string {
|
|||||||
switch s[r] {
|
switch s[r] {
|
||||||
default:
|
default:
|
||||||
p.bug("Expected valid escape code after \\, but got %q.", s[r])
|
p.bug("Expected valid escape code after \\, but got %q.", s[r])
|
||||||
return ""
|
|
||||||
case ' ', '\t':
|
case ' ', '\t':
|
||||||
p.panicItemf(it, "invalid escape: '\\%c'", s[r])
|
p.panicItemf(it, "invalid escape: '\\%c'", s[r])
|
||||||
return ""
|
|
||||||
case 'b':
|
case 'b':
|
||||||
replaced = append(replaced, rune(0x0008))
|
replaced = append(replaced, rune(0x0008))
|
||||||
r += 1
|
r += 1
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -1,7 +1,7 @@
|
|||||||
# github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
|
# github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
|
||||||
github.com/Azure/go-ansiterm
|
github.com/Azure/go-ansiterm
|
||||||
github.com/Azure/go-ansiterm/winterm
|
github.com/Azure/go-ansiterm/winterm
|
||||||
# github.com/BurntSushi/toml v1.1.0
|
# github.com/BurntSushi/toml v1.2.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/BurntSushi/toml
|
github.com/BurntSushi/toml
|
||||||
github.com/BurntSushi/toml/internal
|
github.com/BurntSushi/toml/internal
|
||||||
|
Reference in New Issue
Block a user