Этот коммит содержится в:
Christopher Speller
2017-11-13 09:09:58 -08:00
коммит произвёл GitHub
родитель 7304a61ef5
Коммит 1329aa51b6
474 изменённых файлов: 84159 добавлений и 8829 удалений

1
vendor/github.com/pelletier/go-toml/.gitignore сгенерированный поставляемый
Просмотреть файл

@@ -1 +1,2 @@
test_program/test_program_bin
fuzz/

5
vendor/github.com/pelletier/go-toml/.travis.yml сгенерированный поставляемый
Просмотреть файл

@@ -1,9 +1,8 @@
sudo: false
language: go
go:
- 1.7.6
- 1.8.3
- 1.9
- 1.8.4
- 1.9.1
- tip
matrix:
allow_failures:

18
vendor/github.com/pelletier/go-toml/README.md сгенерированный поставляемый
Просмотреть файл

@@ -57,9 +57,9 @@ type Config struct {
}
doc := []byte(`
[postgres]
user = "pelletier"
password = "mypassword"`)
[Postgres]
User = "pelletier"
Password = "mypassword"`)
config := Config{}
toml.Unmarshal(doc, &config)
@@ -114,6 +114,18 @@ You have to make sure two kind of tests run:
You can run both of them using `./test.sh`.
### Fuzzing
The script `./fuzz.sh` is available to
run [go-fuzz](https://github.com/dvyukov/go-fuzz) on go-toml.
## Versioning
Go-toml follows [Semantic Versioning](http://semver.org/). The supported version
of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of
this document. The last two major versions of Go are supported
(see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)).
## License
The MIT License (MIT). Read [LICENSE](LICENSE).

2
vendor/github.com/pelletier/go-toml/doc.go сгенерированный поставляемый
Просмотреть файл

@@ -17,7 +17,7 @@
// JSONPath-like queries
//
// The package github.com/pelletier/go-toml/query implements a system
// similar to JSONPath to quickly retrive elements of a TOML document using a
// similar to JSONPath to quickly retrieve elements of a TOML document using a
// single expression. See the package documentation for more information.
//
package toml

9
vendor/github.com/pelletier/go-toml/doc_test.go сгенерированный поставляемый
Просмотреть файл

@@ -61,19 +61,24 @@ func ExampleMarshal() {
type Postgres struct {
User string `toml:"user"`
Password string `toml:"password"`
Database string `toml:"db" commented:"true" comment:"not used anymore"`
}
type Config struct {
Postgres Postgres `toml:"postgres"`
Postgres Postgres `toml:"postgres" comment:"Postgres configuration"`
}
config := Config{Postgres{User: "pelletier", Password: "mypassword"}}
config := Config{Postgres{User: "pelletier", Password: "mypassword", Database: "old_database"}}
b, err := toml.Marshal(config)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
// Output:
// # Postgres configuration
// [postgres]
//
// # not used anymore
// # db = "old_database"
// password = "mypassword"
// user = "pelletier"
}

31
vendor/github.com/pelletier/go-toml/fuzz.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,31 @@
// +build gofuzz
package toml
func Fuzz(data []byte) int {
tree, err := LoadBytes(data)
if err != nil {
if tree != nil {
panic("tree must be nil if there is an error")
}
return 0
}
str, err := tree.ToTomlString()
if err != nil {
if str != "" {
panic(`str must be "" if there is an error`)
}
panic(err)
}
tree, err = Load(str)
if err != nil {
if tree != nil {
panic("tree must be nil if there is an error")
}
return 0
}
return 1
}

15
vendor/github.com/pelletier/go-toml/fuzz.sh сгенерированный поставляемый Исполняемый файл
Просмотреть файл

@@ -0,0 +1,15 @@
#! /bin/sh
set -eu
go get github.com/dvyukov/go-fuzz/go-fuzz
go get github.com/dvyukov/go-fuzz/go-fuzz-build
if [ ! -e toml-fuzz.zip ]; then
go-fuzz-build github.com/pelletier/go-toml
fi
rm -fr fuzz
mkdir -p fuzz/corpus
cp *.toml fuzz/corpus
go-fuzz -bin=toml-fuzz.zip -workdir=fuzz

109
vendor/github.com/pelletier/go-toml/keysparsing.go сгенерированный поставляемый
Просмотреть файл

@@ -6,15 +6,37 @@ import (
"bytes"
"errors"
"fmt"
"strconv"
"unicode"
)
var escapeSequenceMap = map[rune]rune{
'b': '\b',
't': '\t',
'n': '\n',
'f': '\f',
'r': '\r',
'"': '"',
'\\': '\\',
}
type parseKeyState int
const (
BARE parseKeyState = iota
BASIC
LITERAL
ESC
UNICODE_4
UNICODE_8
)
func parseKey(key string) ([]string, error) {
groups := []string{}
var buffer bytes.Buffer
inQuotes := false
var hex bytes.Buffer
state := BARE
wasInQuotes := false
escapeNext := false
ignoreSpace := true
expectDot := false
@@ -25,25 +47,67 @@ func parseKey(key string) ([]string, error) {
}
ignoreSpace = false
}
if escapeNext {
buffer.WriteRune(char)
escapeNext = false
if state == ESC {
if char == 'u' {
state = UNICODE_4
hex.Reset()
} else if char == 'U' {
state = UNICODE_8
hex.Reset()
} else if newChar, ok := escapeSequenceMap[char]; ok {
buffer.WriteRune(newChar)
state = BASIC
} else {
return nil, fmt.Errorf(`invalid escape sequence \%c`, char)
}
continue
}
if state == UNICODE_4 || state == UNICODE_8 {
if isHexDigit(char) {
hex.WriteRune(char)
}
if (state == UNICODE_4 && hex.Len() == 4) || (state == UNICODE_8 && hex.Len() == 8) {
if value, err := strconv.ParseInt(hex.String(), 16, 32); err == nil {
buffer.WriteRune(rune(value))
} else {
return nil, err
}
state = BASIC
}
continue
}
switch char {
case '\\':
escapeNext = true
continue
case '"':
if inQuotes {
if state == BASIC {
state = ESC
} else if state == LITERAL {
buffer.WriteRune(char)
}
case '\'':
if state == BARE {
state = LITERAL
} else if state == LITERAL {
groups = append(groups, buffer.String())
buffer.Reset()
wasInQuotes = true
state = BARE
}
expectDot = false
case '"':
if state == BARE {
state = BASIC
} else if state == BASIC {
groups = append(groups, buffer.String())
buffer.Reset()
state = BARE
wasInQuotes = true
}
inQuotes = !inQuotes
expectDot = false
case '.':
if inQuotes {
if state != BARE {
buffer.WriteRune(char)
} else {
if !wasInQuotes {
@@ -58,28 +122,31 @@ func parseKey(key string) ([]string, error) {
wasInQuotes = false
}
case ' ':
if inQuotes {
if state == BASIC {
buffer.WriteRune(char)
} else {
expectDot = true
}
default:
if !inQuotes && !isValidBareChar(char) {
return nil, fmt.Errorf("invalid bare character: %c", char)
}
if !inQuotes && expectDot {
return nil, errors.New("what?")
if state == BARE {
if !isValidBareChar(char) {
return nil, fmt.Errorf("invalid bare character: %c", char)
} else if expectDot {
return nil, errors.New("what?")
}
}
buffer.WriteRune(char)
expectDot = false
}
}
if inQuotes {
// state must be BARE at the end
if state == ESC {
return nil, errors.New("unfinished escape sequence")
} else if state != BARE {
return nil, errors.New("mismatched quotes")
}
if escapeNext {
return nil, errors.New("unfinished escape sequence")
}
if buffer.Len() > 0 {
groups = append(groups, buffer.String())
}

16
vendor/github.com/pelletier/go-toml/keysparsing_test.go сгенерированный поставляемый
Просмотреть файл

@@ -22,7 +22,10 @@ func testResult(t *testing.T, key string, expected []string) {
}
func testError(t *testing.T, key string, expectedError string) {
_, err := parseKey(key)
res, err := parseKey(key)
if err == nil {
t.Fatalf("Expected error, but succesfully parsed key %s", res)
}
if fmt.Sprintf("%s", err) != expectedError {
t.Fatalf("Expected error \"%s\", but got \"%s\".", expectedError, err)
}
@@ -47,6 +50,17 @@ func TestBaseKeyPound(t *testing.T) {
func TestQuotedKeys(t *testing.T) {
testResult(t, `hello."foo".bar`, []string{"hello", "foo", "bar"})
testResult(t, `"hello!"`, []string{"hello!"})
testResult(t, `"hello\tworld"`, []string{"hello\tworld"})
testResult(t, `"\U0001F914"`, []string{"\U0001F914"})
testResult(t, `"\u2764"`, []string{"\u2764"})
testResult(t, `hello.'foo'.bar`, []string{"hello", "foo", "bar"})
testResult(t, `'hello!'`, []string{"hello!"})
testResult(t, `'hello\tworld'`, []string{`hello\tworld`})
testError(t, `"\w"`, `invalid escape sequence \w`)
testError(t, `"\`, `unfinished escape sequence`)
testError(t, `"\t`, `mismatched quotes`)
}
func TestEmptyKey(t *testing.T) {

230
vendor/github.com/pelletier/go-toml/marshal.go сгенерированный поставляемый
Просмотреть файл

@@ -4,17 +4,29 @@ import (
"bytes"
"errors"
"fmt"
"io"
"reflect"
"strconv"
"strings"
"time"
)
type tomlOpts struct {
name string
comment string
commented bool
include bool
omitempty bool
}
type encOpts struct {
quoteMapKeys bool
}
var encOptsDefaults = encOpts{
quoteMapKeys: false,
}
var timeType = reflect.TypeOf(time.Time{})
var marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
@@ -94,8 +106,15 @@ encoder, except that there is no concept of a Marshaler interface or MarshalTOML
function for sub-structs, and currently only definite types can be marshaled
(i.e. no `interface{}`).
The following struct annotations are supported:
toml:"Field" Overrides the field's name to output.
omitempty When set, empty values and groups are not emitted.
comment:"comment" Emits a # comment on the same line. This supports new lines.
commented:"true" Emits the value as commented.
Note that pointers are automatically assigned the "omitempty" option, as TOML
explicity does not handle null values (saying instead the label should be
explicitly does not handle null values (saying instead the label should be
dropped).
Tree structural types and corresponding marshal types:
@@ -115,6 +134,47 @@ Tree primitive types and corresponding marshal types:
time.Time time.Time{}, pointers to same
*/
func Marshal(v interface{}) ([]byte, error) {
return NewEncoder(nil).marshal(v)
}
// Encoder writes TOML values to an output stream.
type Encoder struct {
w io.Writer
encOpts
}
// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{
w: w,
encOpts: encOptsDefaults,
}
}
// Encode writes the TOML encoding of v to the stream.
//
// See the documentation for Marshal for details.
func (e *Encoder) Encode(v interface{}) error {
b, err := e.marshal(v)
if err != nil {
return err
}
if _, err := e.w.Write(b); err != nil {
return err
}
return nil
}
// QuoteMapKeys sets up the encoder to encode
// maps with string type keys with quoted TOML keys.
//
// This relieves the character limitations on map keys.
func (e *Encoder) QuoteMapKeys(v bool) *Encoder {
e.quoteMapKeys = v
return e
}
func (e *Encoder) marshal(v interface{}) ([]byte, error) {
mtype := reflect.TypeOf(v)
if mtype.Kind() != reflect.Struct {
return []byte{}, errors.New("Only a struct can be marshaled to TOML")
@@ -123,7 +183,7 @@ func Marshal(v interface{}) ([]byte, error) {
if isCustomMarshaler(mtype) {
return callCustomMarshaler(sval)
}
t, err := valueToTree(mtype, sval)
t, err := e.valueToTree(mtype, sval)
if err != nil {
return []byte{}, err
}
@@ -132,9 +192,9 @@ func Marshal(v interface{}) ([]byte, error) {
}
// Convert given marshal struct or map value to toml tree
func valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) {
func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) {
if mtype.Kind() == reflect.Ptr {
return valueToTree(mtype.Elem(), mval.Elem())
return e.valueToTree(mtype.Elem(), mval.Elem())
}
tval := newTree()
switch mtype.Kind() {
@@ -143,31 +203,39 @@ func valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) {
mtypef, mvalf := mtype.Field(i), mval.Field(i)
opts := tomlOptions(mtypef)
if opts.include && (!opts.omitempty || !isZero(mvalf)) {
val, err := valueToToml(mtypef.Type, mvalf)
val, err := e.valueToToml(mtypef.Type, mvalf)
if err != nil {
return nil, err
}
tval.Set(opts.name, val)
tval.Set(opts.name, opts.comment, opts.commented, val)
}
}
case reflect.Map:
for _, key := range mval.MapKeys() {
mvalf := mval.MapIndex(key)
val, err := valueToToml(mtype.Elem(), mvalf)
val, err := e.valueToToml(mtype.Elem(), mvalf)
if err != nil {
return nil, err
}
tval.Set(key.String(), val)
if e.quoteMapKeys {
keyStr, err := tomlValueStringRepresentation(key.String())
if err != nil {
return nil, err
}
tval.SetPath([]string{keyStr}, "", false, val)
} else {
tval.Set(key.String(), "", false, val)
}
}
}
return tval, nil
}
// Convert given marshal slice to slice of Toml trees
func valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) {
func (e *Encoder) valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) {
tval := make([]*Tree, mval.Len(), mval.Len())
for i := 0; i < mval.Len(); i++ {
val, err := valueToTree(mtype.Elem(), mval.Index(i))
val, err := e.valueToTree(mtype.Elem(), mval.Index(i))
if err != nil {
return nil, err
}
@@ -177,10 +245,10 @@ func valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) {
}
// Convert given marshal slice to slice of toml values
func valueToOtherSlice(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
func (e *Encoder) valueToOtherSlice(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
tval := make([]interface{}, mval.Len(), mval.Len())
for i := 0; i < mval.Len(); i++ {
val, err := valueToToml(mtype.Elem(), mval.Index(i))
val, err := e.valueToToml(mtype.Elem(), mval.Index(i))
if err != nil {
return nil, err
}
@@ -190,19 +258,19 @@ func valueToOtherSlice(mtype reflect.Type, mval reflect.Value) (interface{}, err
}
// Convert given marshal value to toml value
func valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
if mtype.Kind() == reflect.Ptr {
return valueToToml(mtype.Elem(), mval.Elem())
return e.valueToToml(mtype.Elem(), mval.Elem())
}
switch {
case isCustomMarshaler(mtype):
return callCustomMarshaler(mval)
case isTree(mtype):
return valueToTree(mtype, mval)
return e.valueToTree(mtype, mval)
case isTreeSlice(mtype):
return valueToTreeSlice(mtype, mval)
return e.valueToTreeSlice(mtype, mval)
case isOtherSlice(mtype):
return valueToOtherSlice(mtype, mval)
return e.valueToOtherSlice(mtype, mval)
default:
switch mtype.Kind() {
case reflect.Bool:
@@ -227,17 +295,16 @@ func valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
// Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for
// sub-structs, and only definite types can be unmarshaled.
func (t *Tree) Unmarshal(v interface{}) error {
mtype := reflect.TypeOf(v)
if mtype.Kind() != reflect.Ptr || mtype.Elem().Kind() != reflect.Struct {
return errors.New("Only a pointer to struct can be unmarshaled from TOML")
}
d := Decoder{tval: t}
return d.unmarshal(v)
}
sval, err := valueFromTree(mtype.Elem(), t)
if err != nil {
return err
}
reflect.ValueOf(v).Elem().Set(sval)
return nil
// Marshal returns the TOML encoding of Tree.
// See Marshal() documentation for types mapping table.
func (t *Tree) Marshal() ([]byte, error) {
var buf bytes.Buffer
err := NewEncoder(&buf).Encode(t)
return buf.Bytes(), err
}
// Unmarshal parses the TOML-encoded data and stores the result in the value
@@ -246,6 +313,10 @@ func (t *Tree) Unmarshal(v interface{}) error {
// sub-structs, and currently only definite types can be unmarshaled to (i.e. no
// `interface{}`).
//
// The following struct annotations are supported:
//
// toml:"Field" Overrides the field's name to map to.
//
// See Marshal() documentation for types mapping table.
func Unmarshal(data []byte, v interface{}) error {
t, err := LoadReader(bytes.NewReader(data))
@@ -255,10 +326,52 @@ func Unmarshal(data []byte, v interface{}) error {
return t.Unmarshal(v)
}
// Decoder reads and decodes TOML values from an input stream.
type Decoder struct {
r io.Reader
tval *Tree
encOpts
}
// NewDecoder returns a new decoder that reads from r.
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{
r: r,
encOpts: encOptsDefaults,
}
}
// Decode reads a TOML-encoded value from it's input
// and unmarshals it in the value pointed at by v.
//
// See the documentation for Marshal for details.
func (d *Decoder) Decode(v interface{}) error {
var err error
d.tval, err = LoadReader(d.r)
if err != nil {
return err
}
return d.unmarshal(v)
}
func (d *Decoder) unmarshal(v interface{}) error {
mtype := reflect.TypeOf(v)
if mtype.Kind() != reflect.Ptr || mtype.Elem().Kind() != reflect.Struct {
return errors.New("Only a pointer to struct can be unmarshaled from TOML")
}
sval, err := d.valueFromTree(mtype.Elem(), d.tval)
if err != nil {
return err
}
reflect.ValueOf(v).Elem().Set(sval)
return nil
}
// Convert toml tree to marshal struct or map, using marshal type
func valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) {
func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) {
if mtype.Kind() == reflect.Ptr {
return unwrapPointer(mtype, tval)
return d.unwrapPointer(mtype, tval)
}
var mval reflect.Value
switch mtype.Kind() {
@@ -276,7 +389,7 @@ func valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) {
continue
}
val := tval.Get(key)
mvalf, err := valueFromToml(mtypef.Type, val)
mvalf, err := d.valueFromToml(mtypef.Type, val)
if err != nil {
return mval, formatError(err, tval.GetPosition(key))
}
@@ -288,8 +401,9 @@ func valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) {
case reflect.Map:
mval = reflect.MakeMap(mtype)
for _, key := range tval.Keys() {
val := tval.Get(key)
mvalf, err := valueFromToml(mtype.Elem(), val)
// TODO: path splits key
val := tval.GetPath([]string{key})
mvalf, err := d.valueFromToml(mtype.Elem(), val)
if err != nil {
return mval, formatError(err, tval.GetPosition(key))
}
@@ -300,10 +414,10 @@ func valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) {
}
// Convert toml value to marshal struct/map slice, using marshal type
func valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) {
func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) {
mval := reflect.MakeSlice(mtype, len(tval), len(tval))
for i := 0; i < len(tval); i++ {
val, err := valueFromTree(mtype.Elem(), tval[i])
val, err := d.valueFromTree(mtype.Elem(), tval[i])
if err != nil {
return mval, err
}
@@ -313,10 +427,10 @@ func valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error)
}
// Convert toml value to marshal primitive slice, using marshal type
func valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) {
func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) {
mval := reflect.MakeSlice(mtype, len(tval), len(tval))
for i := 0; i < len(tval); i++ {
val, err := valueFromToml(mtype.Elem(), tval[i])
val, err := d.valueFromToml(mtype.Elem(), tval[i])
if err != nil {
return mval, err
}
@@ -326,17 +440,30 @@ func valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value,
}
// Convert toml value to marshal value, using marshal type
func valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
if mtype.Kind() == reflect.Ptr {
return unwrapPointer(mtype, tval)
return d.unwrapPointer(mtype, tval)
}
switch {
case isTree(mtype):
return valueFromTree(mtype, tval.(*Tree))
case isTreeSlice(mtype):
return valueFromTreeSlice(mtype, tval.([]*Tree))
case isOtherSlice(mtype):
return valueFromOtherSlice(mtype, tval.([]interface{}))
switch tval.(type) {
case *Tree:
if isTree(mtype) {
return d.valueFromTree(mtype, tval.(*Tree))
} else {
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
}
case []*Tree:
if isTreeSlice(mtype) {
return d.valueFromTreeSlice(mtype, tval.([]*Tree))
} else {
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
}
case []interface{}:
if isOtherSlice(mtype) {
return d.valueFromOtherSlice(mtype, tval.([]interface{}))
} else {
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
}
default:
switch mtype.Kind() {
case reflect.Bool:
@@ -430,13 +557,13 @@ func valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error)
}
return reflect.ValueOf(val), nil
default:
return reflect.ValueOf(nil), fmt.Errorf("Unmarshal can't handle %v(%v)", mtype, mtype.Kind())
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
}
}
}
func unwrapPointer(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
val, err := valueFromToml(mtype.Elem(), tval)
func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
val, err := d.valueFromToml(mtype.Elem(), tval)
if err != nil {
return reflect.ValueOf(nil), err
}
@@ -448,7 +575,12 @@ func unwrapPointer(mtype reflect.Type, tval interface{}) (reflect.Value, error)
func tomlOptions(vf reflect.StructField) tomlOpts {
tag := vf.Tag.Get("toml")
parse := strings.Split(tag, ",")
result := tomlOpts{vf.Name, true, false}
var comment string
if c := vf.Tag.Get("comment"); c != "" {
comment = c
}
commented, _ := strconv.ParseBool(vf.Tag.Get("commented"))
result := tomlOpts{name: vf.Name, comment: comment, commented: commented, include: true, omitempty: false}
if parse[0] != "" {
if parse[0] == "-" && len(parse) == 1 {
result.include = false

134
vendor/github.com/pelletier/go-toml/marshal_test.go сгенерированный поставляемый
Просмотреть файл

@@ -6,6 +6,7 @@ import (
"fmt"
"io/ioutil"
"reflect"
"strings"
"testing"
"time"
)
@@ -508,6 +509,14 @@ func TestPointerUnmarshal(t *testing.T) {
}
}
func TestUnmarshalTypeMismatch(t *testing.T) {
result := pointerMarshalTestStruct{}
err := Unmarshal([]byte("List = 123"), &result)
if !strings.HasPrefix(err.Error(), "(1, 1): Can't convert 123(int64) to []string(slice)") {
t.Errorf("Type mismatch must be reported: got %v", err.Error())
}
}
type nestedMarshalTestStruct struct {
String [][]string
//Struct [][]basicMarshalTestSubStruct
@@ -598,3 +607,128 @@ func TestNestedCustomMarshaler(t *testing.T) {
t.Errorf("Bad nested custom marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
}
}
var commentTestToml = []byte(`
# it's a comment on type
[postgres]
# isCommented = "dvalue"
noComment = "cvalue"
# A comment on AttrB with a
# break line
password = "bvalue"
# A comment on AttrA
user = "avalue"
[[postgres.My]]
# a comment on my on typeC
My = "Foo"
[[postgres.My]]
# a comment on my on typeC
My = "Baar"
`)
func TestMarshalComment(t *testing.T) {
type TypeC struct {
My string `comment:"a comment on my on typeC"`
}
type TypeB struct {
AttrA string `toml:"user" comment:"A comment on AttrA"`
AttrB string `toml:"password" comment:"A comment on AttrB with a\n break line"`
AttrC string `toml:"noComment"`
AttrD string `toml:"isCommented" commented:"true"`
My []TypeC
}
type TypeA struct {
TypeB TypeB `toml:"postgres" comment:"it's a comment on type"`
}
ta := []TypeC{{My: "Foo"}, {My: "Baar"}}
config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue", AttrC: "cvalue", AttrD: "dvalue", My: ta}}
result, err := Marshal(config)
if err != nil {
t.Fatal(err)
}
expected := commentTestToml
if !bytes.Equal(result, expected) {
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
}
}
type mapsTestStruct struct {
Simple map[string]string
Paths map[string]string
Other map[string]float64
X struct {
Y struct {
Z map[string]bool
}
}
}
var mapsTestData = mapsTestStruct{
Simple: map[string]string{
"one plus one": "two",
"next": "three",
},
Paths: map[string]string{
"/this/is/a/path": "/this/is/also/a/path",
"/heloo.txt": "/tmp/lololo.txt",
},
Other: map[string]float64{
"testing": 3.9999,
},
X: struct{ Y struct{ Z map[string]bool } }{
Y: struct{ Z map[string]bool }{
Z: map[string]bool{
"is.Nested": true,
},
},
},
}
var mapsTestToml = []byte(`
[Other]
"testing" = 3.9999
[Paths]
"/heloo.txt" = "/tmp/lololo.txt"
"/this/is/a/path" = "/this/is/also/a/path"
[Simple]
"next" = "three"
"one plus one" = "two"
[X]
[X.Y]
[X.Y.Z]
"is.Nested" = true
`)
func TestEncodeQuotedMapKeys(t *testing.T) {
var buf bytes.Buffer
if err := NewEncoder(&buf).QuoteMapKeys(true).Encode(mapsTestData); err != nil {
t.Fatal(err)
}
result := buf.Bytes()
expected := mapsTestToml
if !bytes.Equal(result, expected) {
t.Errorf("Bad maps marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
}
}
func TestDecodeQuotedMapKeys(t *testing.T) {
result := mapsTestStruct{}
err := NewDecoder(bytes.NewBuffer(mapsTestToml)).Decode(&result)
expected := mapsTestData
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result, expected) {
t.Errorf("Bad maps unmarshal: expected %v, got %v", expected, result)
}
}

6
vendor/github.com/pelletier/go-toml/parser.go сгенерированный поставляемый
Просмотреть файл

@@ -110,7 +110,7 @@ func (p *tomlParser) parseGroupArray() tomlParserStateFn {
newTree := newTree()
newTree.position = startToken.Position
array = append(array, newTree)
p.tree.SetPath(p.currentTable, array)
p.tree.SetPath(p.currentTable, "", false, array)
// remove all keys that were children of this table array
prefix := key.val + "."
@@ -205,7 +205,7 @@ func (p *tomlParser) parseAssign() tomlParserStateFn {
case *Tree, []*Tree:
toInsert = value
default:
toInsert = &tomlValue{value, key.Position}
toInsert = &tomlValue{value: value, position: key.Position}
}
targetNode.values[keyVal] = toInsert
return p.parseStart
@@ -299,7 +299,7 @@ Loop:
key := p.getToken()
p.assume(tokenEqual)
value := p.parseRvalue()
tree.Set(key.val, value)
tree.Set(key.val, "", false, value)
case tokenComma:
if previous == nil {
p.raiseError(follow, "inline table cannot start with a comma")

2
vendor/github.com/pelletier/go-toml/parser_test.go сгенерированный поставляемый
Просмотреть файл

@@ -46,7 +46,7 @@ func assertTree(t *testing.T, tree *Tree, err error, ref map[string]interface{})
func TestCreateSubTree(t *testing.T) {
tree := newTree()
tree.createSubTree([]string{"a", "b", "c"}, Position{})
tree.Set("a.b.c", 42)
tree.Set("a.b.c", "", false, 42)
if tree.Get("a.b.c") != 42 {
t.Fail()
}

2
vendor/github.com/pelletier/go-toml/query/doc.go сгенерированный поставляемый
Просмотреть файл

@@ -139,7 +139,7 @@
// Compiled Queries
//
// Queries may be executed directly on a Tree object, or compiled ahead
// of time and executed discretely. The former is more convienent, but has the
// of time and executed discretely. The former is more convenient, but has the
// penalty of having to recompile the query expression each time.
//
// // basic query

26
vendor/github.com/pelletier/go-toml/toml.go сгенерированный поставляемый
Просмотреть файл

@@ -11,14 +11,18 @@ import (
)
type tomlValue struct {
value interface{} // string, int64, uint64, float64, bool, time.Time, [] of any of this list
position Position
value interface{} // string, int64, uint64, float64, bool, time.Time, [] of any of this list
comment string
commented bool
position Position
}
// Tree is the result of the parsing of a TOML file.
type Tree struct {
values map[string]interface{} // string -> *tomlValue, *Tree, []*Tree
position Position
values map[string]interface{} // string -> *tomlValue, *Tree, []*Tree
comment string
commented bool
position Position
}
func newTree() *Tree {
@@ -177,14 +181,14 @@ func (t *Tree) GetDefault(key string, def interface{}) interface{} {
// Set an element in the tree.
// Key is a dot-separated path (e.g. a.b.c).
// Creates all necessary intermediate trees, if needed.
func (t *Tree) Set(key string, value interface{}) {
t.SetPath(strings.Split(key, "."), value)
func (t *Tree) Set(key string, comment string, commented bool, value interface{}) {
t.SetPath(strings.Split(key, "."), comment, commented, value)
}
// SetPath sets an element in the tree.
// Keys is an array of path elements (e.g. {"a","b","c"}).
// Creates all necessary intermediate trees, if needed.
func (t *Tree) SetPath(keys []string, value interface{}) {
func (t *Tree) SetPath(keys []string, comment string, commented bool, value interface{}) {
subtree := t
for _, intermediateKey := range keys[:len(keys)-1] {
nextTree, exists := subtree.values[intermediateKey]
@@ -209,13 +213,17 @@ func (t *Tree) SetPath(keys []string, value interface{}) {
switch value.(type) {
case *Tree:
tt := value.(*Tree)
tt.comment = comment
toInsert = value
case []*Tree:
toInsert = value
case *tomlValue:
toInsert = value
tt := value.(*tomlValue)
tt.comment = comment
toInsert = tt
default:
toInsert = &tomlValue{value: value}
toInsert = &tomlValue{value: value, comment: comment, commented: commented}
}
subtree.values[keys[len(keys)-1]] = toInsert

6
vendor/github.com/pelletier/go-toml/tomltree_create.go сгенерированный поставляемый
Просмотреть файл

@@ -104,7 +104,7 @@ func sliceToTree(object interface{}) (interface{}, error) {
}
arrayValue = reflect.Append(arrayValue, reflect.ValueOf(simpleValue))
}
return &tomlValue{arrayValue.Interface(), Position{}}, nil
return &tomlValue{value: arrayValue.Interface(), position: Position{}}, nil
}
func toTree(object interface{}) (interface{}, error) {
@@ -127,7 +127,7 @@ func toTree(object interface{}) (interface{}, error) {
}
values[key.String()] = newValue
}
return &Tree{values, Position{}}, nil
return &Tree{values: values, position: Position{}}, nil
}
if value.Kind() == reflect.Array || value.Kind() == reflect.Slice {
@@ -138,5 +138,5 @@ func toTree(object interface{}) (interface{}, error) {
if err != nil {
return nil, err
}
return &tomlValue{simpleValue, Position{}}, nil
return &tomlValue{value: simpleValue, position: Position{}}, nil
}

43
vendor/github.com/pelletier/go-toml/tomltree_write.go сгенерированный поставляемый
Просмотреть файл

@@ -118,7 +118,24 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
return bytesCount, err
}
writtenBytesCount, err := writeStrings(w, indent, k, " = ", repr, "\n")
if v.comment != "" {
comment := strings.Replace(v.comment, "\n", "\n"+indent+"#", -1)
start := "# "
if strings.HasPrefix(comment, "#") {
start = ""
}
writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment, "\n")
bytesCount += int64(writtenBytesCountComment)
if errc != nil {
return bytesCount, errc
}
}
var commented string
if v.commented {
commented = "# "
}
writtenBytesCount, err := writeStrings(w, indent, commented, k, " = ", repr, "\n")
bytesCount += int64(writtenBytesCount)
if err != nil {
return bytesCount, err
@@ -132,11 +149,31 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
if keyspace != "" {
combinedKey = keyspace + "." + combinedKey
}
var commented string
if t.commented {
commented = "# "
}
switch node := v.(type) {
// node has to be of those two types given how keys are sorted above
case *Tree:
writtenBytesCount, err := writeStrings(w, "\n", indent, "[", combinedKey, "]\n")
tv, ok := t.values[k].(*Tree)
if !ok {
return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k])
}
if tv.comment != "" {
comment := strings.Replace(tv.comment, "\n", "\n"+indent+"#", -1)
start := "# "
if strings.HasPrefix(comment, "#") {
start = ""
}
writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment)
bytesCount += int64(writtenBytesCountComment)
if errc != nil {
return bytesCount, errc
}
}
writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[", combinedKey, "]\n")
bytesCount += int64(writtenBytesCount)
if err != nil {
return bytesCount, err
@@ -147,7 +184,7 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
}
case []*Tree:
for _, subTree := range node {
writtenBytesCount, err := writeStrings(w, "\n", indent, "[[", combinedKey, "]]\n")
writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[[", combinedKey, "]]\n")
bytesCount += int64(writtenBytesCount)
if err != nil {
return bytesCount, err

16
vendor/github.com/pelletier/go-toml/tomltree_write_test.go сгенерированный поставляемый
Просмотреть файл

@@ -30,7 +30,7 @@ func (f *failingWriter) Write(p []byte) (n int, err error) {
f.buffer.Write(p[:toWrite])
f.written = f.failAt
return toWrite, fmt.Errorf("failingWriter failed after writting %d bytes", f.written)
return toWrite, fmt.Errorf("failingWriter failed after writing %d bytes", f.written)
}
func assertErrorString(t *testing.T, expected string, err error) {
@@ -161,13 +161,13 @@ func TestTreeWriteToInvalidTreeSimpleValue(t *testing.T) {
}
func TestTreeWriteToInvalidTreeTomlValue(t *testing.T) {
tree := Tree{values: map[string]interface{}{"foo": &tomlValue{int8(1), Position{}}}}
tree := Tree{values: map[string]interface{}{"foo": &tomlValue{value: int8(1), comment: "", position: Position{}}}}
_, err := tree.ToTomlString()
assertErrorString(t, "unsupported value type int8: 1", err)
}
func TestTreeWriteToInvalidTreeTomlValueArray(t *testing.T) {
tree := Tree{values: map[string]interface{}{"foo": &tomlValue{[]interface{}{int8(1)}, Position{}}}}
tree := Tree{values: map[string]interface{}{"foo": &tomlValue{value: int8(1), comment: "", position: Position{}}}}
_, err := tree.ToTomlString()
assertErrorString(t, "unsupported value type int8: 1", err)
}
@@ -176,7 +176,7 @@ func TestTreeWriteToFailingWriterInSimpleValue(t *testing.T) {
toml, _ := Load(`a = 2`)
writer := failingWriter{failAt: 0, written: 0}
_, err := toml.WriteTo(&writer)
assertErrorString(t, "failingWriter failed after writting 0 bytes", err)
assertErrorString(t, "failingWriter failed after writing 0 bytes", err)
}
func TestTreeWriteToFailingWriterInTable(t *testing.T) {
@@ -185,11 +185,11 @@ func TestTreeWriteToFailingWriterInTable(t *testing.T) {
a = 2`)
writer := failingWriter{failAt: 2, written: 0}
_, err := toml.WriteTo(&writer)
assertErrorString(t, "failingWriter failed after writting 2 bytes", err)
assertErrorString(t, "failingWriter failed after writing 2 bytes", err)
writer = failingWriter{failAt: 13, written: 0}
_, err = toml.WriteTo(&writer)
assertErrorString(t, "failingWriter failed after writting 13 bytes", err)
assertErrorString(t, "failingWriter failed after writing 13 bytes", err)
}
func TestTreeWriteToFailingWriterInArray(t *testing.T) {
@@ -198,11 +198,11 @@ func TestTreeWriteToFailingWriterInArray(t *testing.T) {
a = 2`)
writer := failingWriter{failAt: 2, written: 0}
_, err := toml.WriteTo(&writer)
assertErrorString(t, "failingWriter failed after writting 2 bytes", err)
assertErrorString(t, "failingWriter failed after writing 2 bytes", err)
writer = failingWriter{failAt: 15, written: 0}
_, err = toml.WriteTo(&writer)
assertErrorString(t, "failingWriter failed after writting 15 bytes", err)
assertErrorString(t, "failingWriter failed after writing 15 bytes", err)
}
func TestTreeWriteToMapExampleFile(t *testing.T) {