├── .gitignore ├── kit.go ├── cfg ├── 0_default.yml ├── 1_config.yml ├── yaml.go ├── json.go ├── toml.go ├── cfg.go └── cfg_test.go ├── vendor ├── github.com │ ├── mitchellh │ │ └── mapstructure │ │ │ ├── go.mod │ │ │ ├── .travis.yml │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── error.go │ │ │ ├── README.md │ │ │ └── decode_hooks.go │ ├── BurntSushi │ │ └── toml │ │ │ ├── session.vim │ │ │ ├── .gitignore │ │ │ ├── COMPATIBLE │ │ │ ├── .travis.yml │ │ │ ├── Makefile │ │ │ ├── encoding_types_1.1.go │ │ │ ├── encoding_types.go │ │ │ ├── COPYING │ │ │ ├── doc.go │ │ │ ├── type_check.go │ │ │ ├── decode_meta.go │ │ │ ├── README.md │ │ │ └── type_fields.go │ ├── imdario │ │ └── mergo │ │ │ ├── .travis.yml │ │ │ ├── .gitignore │ │ │ ├── doc.go │ │ │ ├── LICENSE │ │ │ ├── mergo.go │ │ │ ├── CODE_OF_CONDUCT.md │ │ │ ├── map.go │ │ │ └── merge.go │ ├── stretchr │ │ └── testify │ │ │ ├── assert │ │ │ ├── assertion_format.go.tmpl │ │ │ ├── assertion_forward.go.tmpl │ │ │ ├── errors.go │ │ │ ├── forward_assertions.go │ │ │ ├── doc.go │ │ │ └── http_assertions.go │ │ │ └── LICENSE │ ├── pkg │ │ └── errors │ │ │ ├── .travis.yml │ │ │ ├── .gitignore │ │ │ ├── appveyor.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── stack.go │ │ │ └── errors.go │ ├── davecgh │ │ └── go-spew │ │ │ ├── LICENSE │ │ │ └── spew │ │ │ ├── bypasssafe.go │ │ │ ├── bypass.go │ │ │ ├── spew.go │ │ │ └── doc.go │ └── pmezard │ │ └── go-difflib │ │ └── LICENSE ├── gopkg.in │ └── yaml.v2 │ │ ├── go.mod │ │ ├── .travis.yml │ │ ├── NOTICE │ │ ├── writerc.go │ │ ├── LICENSE.libyaml │ │ ├── sorter.go │ │ ├── README.md │ │ ├── yamlprivateh.go │ │ └── resolve.go ├── golang.org │ └── x │ │ └── crypto │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── PATENTS │ │ ├── LICENSE │ │ ├── pbkdf2 │ │ └── pbkdf2.go │ │ └── scrypt │ │ └── scrypt.go └── modules.txt ├── .travis.yml ├── query ├── errors.go ├── dialect.go ├── update_test.go ├── insert_test.go ├── query_test.go ├── insert.go ├── query.go ├── update.go ├── operator.go └── cassandra_dialect.go ├── valid ├── number_test.go ├── validator.go ├── generic_test.go ├── generic.go ├── number.go ├── text_test.go └── text.go ├── go.mod ├── .editorconfig ├── str ├── case_test.go └── case.go ├── security ├── scrypt_test.go └── scrypt.go ├── README.md ├── expr ├── expr.go ├── stack.go ├── expr_test.go └── eval.go ├── retry ├── retry_test.go └── retry.go ├── LICENSE ├── di ├── di_test.go └── di.go ├── go.sum └── id ├── id_test.go └── id.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /kit.go: -------------------------------------------------------------------------------- 1 | package kit 2 | -------------------------------------------------------------------------------- /cfg/0_default.yml: -------------------------------------------------------------------------------- 1 | service: 2 | port: 8080 3 | timeout: 5s 4 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mitchellh/mapstructure 2 | -------------------------------------------------------------------------------- /cfg/1_config.yml: -------------------------------------------------------------------------------- 1 | name: "App" 2 | service: 3 | port: 4200 4 | ids: [1, 2, 42] 5 | factor: 3.14 6 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/session.vim: -------------------------------------------------------------------------------- 1 | au BufWritePost *.go silent!make tags > /dev/null 2>&1 2 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/.gitignore: -------------------------------------------------------------------------------- 1 | TAGS 2 | tags 3 | .*.swp 4 | tomlcheck/tomlcheck 5 | toml.test 6 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - "1.11.x" 5 | - tip 6 | 7 | script: 8 | - go test 9 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/go.mod: -------------------------------------------------------------------------------- 1 | module "gopkg.in/yaml.v2" 2 | 3 | require ( 4 | "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405 5 | ) 6 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/COMPATIBLE: -------------------------------------------------------------------------------- 1 | Compatible with TOML version 2 | [v0.4.0](https://github.com/toml-lang/toml/blob/v0.4.0/versions/en/toml-v0.4.0.md) 3 | 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: false 3 | 4 | sudo: required 5 | 6 | services: 7 | - cassandra 8 | 9 | language: go 10 | 11 | go: 12 | - "1.11.x" 13 | 14 | script: go test -v ./... 15 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.4 5 | - 1.5 6 | - 1.6 7 | - 1.7 8 | - 1.8 9 | - 1.9 10 | - tip 11 | 12 | go_import_path: gopkg.in/yaml.v2 13 | -------------------------------------------------------------------------------- /query/errors.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | var ( 8 | ErrInvalidCondition = errors.New("invalid condition") 9 | ErrInvalidDialect = errors.New("invalid dialect") 10 | ) 11 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at https://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at https://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | install: 3 | - go get -t 4 | - go get golang.org/x/tools/cmd/cover 5 | - go get github.com/mattn/goveralls 6 | script: 7 | - $HOME/gopath/bin/goveralls -service=travis-ci -repotoken $COVERALLS_TOKEN 8 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl: -------------------------------------------------------------------------------- 1 | {{.CommentFormat}} 2 | func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool { 3 | if h, ok := t.(tHelper); ok { h.Helper() } 4 | return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}}) 5 | } 6 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl: -------------------------------------------------------------------------------- 1 | {{.CommentWithoutT "a"}} 2 | func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { 3 | if h, ok := a.t.(tHelper); ok { h.Helper() } 4 | return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) 5 | } 6 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go_import_path: github.com/pkg/errors 3 | go: 4 | - 1.4.x 5 | - 1.5.x 6 | - 1.6.x 7 | - 1.7.x 8 | - 1.8.x 9 | - 1.9.x 10 | - 1.10.x 11 | - 1.11.x 12 | - tip 13 | 14 | script: 15 | - go test -v ./... 16 | -------------------------------------------------------------------------------- /valid/number_test.go: -------------------------------------------------------------------------------- 1 | package valid 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestNumberRangeFloat(t *testing.T) { 10 | v := New( 11 | Range(2, 5), 12 | ) 13 | assert.NoError(t, v.Validate(3)) 14 | assert.Equal(t, ErrNumberOutOfRange, v.Validate(6)) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.1 4 | - 1.2 5 | - 1.3 6 | - 1.4 7 | - 1.5 8 | - 1.6 9 | - tip 10 | install: 11 | - go install ./... 12 | - go get github.com/BurntSushi/toml-test 13 | script: 14 | - export PATH="$PATH:$HOME/gopath/bin" 15 | - make test 16 | -------------------------------------------------------------------------------- /query/dialect.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | type DialectKind uint8 4 | 5 | const ( 6 | DialectKindCassandra DialectKind = iota 7 | ) 8 | 9 | type dialect interface { 10 | BuildQuery(q Query) (string, []interface{}, error) 11 | BuildInsert(i Insert) (string, []interface{}, error) 12 | BuildUpdate(u Update) (string, []interface{}, error) 13 | } 14 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tinrab/kit 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/BurntSushi/toml v0.3.1 7 | github.com/imdario/mergo v0.3.7 8 | github.com/mitchellh/mapstructure v1.1.2 9 | github.com/pkg/errors v0.8.1 10 | github.com/stretchr/testify v1.3.0 11 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c 12 | gopkg.in/yaml.v2 v2.2.2 13 | ) 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.go] 15 | indent_style = tab 16 | indent_size = 4 17 | 18 | [Makefile] 19 | indent_style = tab 20 | indent_size = 4 21 | -------------------------------------------------------------------------------- /str/case_test.go: -------------------------------------------------------------------------------- 1 | package str 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestToSnakeCase(t *testing.T) { 10 | cases := [][]string{ 11 | {"aB", "a_b"}, 12 | {"a42", "a42"}, 13 | {"AAb", "a_ab"}, 14 | {"A_b", "a_b"}, 15 | } 16 | 17 | for _, c := range cases { 18 | assert.Equal(t, c[1], ToSnakeCase(c[0])) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/Makefile: -------------------------------------------------------------------------------- 1 | install: 2 | go install ./... 3 | 4 | test: install 5 | go test -v 6 | toml-test toml-test-decoder 7 | toml-test -encoder toml-test-encoder 8 | 9 | fmt: 10 | gofmt -w *.go */*.go 11 | colcheck *.go */*.go 12 | 13 | tags: 14 | find ./ -name '*.go' -print0 | xargs -0 gotags > TAGS 15 | 16 | push: 17 | git push origin master 18 | git push github master 19 | 20 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/errors.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // AnError is an error instance useful for testing. If the code does not care 8 | // about error specifics, and only needs to return the error for example, this 9 | // error should be used to make the test code more readable. 10 | var AnError = errors.New("assert.AnError general error for testing") 11 | -------------------------------------------------------------------------------- /security/scrypt_test.go: -------------------------------------------------------------------------------- 1 | package security 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestScrypt(t *testing.T) { 9 | data := []byte("1234") 10 | hash, err := ScryptToBase64(data, 1<<15, 8, 1, 32) 11 | assert.NoError(t, err) 12 | 13 | assert.True(t, ScryptEqualsBase64([]byte("1234"), hash)) 14 | assert.False(t, ScryptEqualsBase64([]byte("12345"), hash)) 15 | } 16 | -------------------------------------------------------------------------------- /cfg/yaml.go: -------------------------------------------------------------------------------- 1 | package cfg 2 | 3 | import ( 4 | "github.com/imdario/mergo" 5 | "gopkg.in/yaml.v2" 6 | ) 7 | 8 | func (c *Config) LoadYAMLString(s string) error { 9 | return c.LoadYAML([]byte(s)) 10 | } 11 | 12 | func (c *Config) LoadYAML(data []byte) error { 13 | res := make(map[string]interface{}) 14 | if err := yaml.Unmarshal(data, &res); err != nil { 15 | return err 16 | } 17 | return mergo.Merge(&c.Data, res, mergo.WithOverride) 18 | } 19 | -------------------------------------------------------------------------------- /cfg/json.go: -------------------------------------------------------------------------------- 1 | package cfg 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/imdario/mergo" 7 | ) 8 | 9 | func (c *Config) LoadJSONString(s string) error { 10 | return c.LoadJSON([]byte(s)) 11 | } 12 | 13 | func (c *Config) LoadJSON(data []byte) error { 14 | res := make(map[string]interface{}) 15 | if err := json.Unmarshal(data, &res); err != nil { 16 | return err 17 | } 18 | return mergo.Merge(&c.Data, res, mergo.WithOverride) 19 | } 20 | -------------------------------------------------------------------------------- /cfg/toml.go: -------------------------------------------------------------------------------- 1 | package cfg 2 | 3 | import ( 4 | "github.com/BurntSushi/toml" 5 | "github.com/imdario/mergo" 6 | ) 7 | 8 | func (c *Config) LoadTOMLString(s string) error { 9 | return c.LoadTOML([]byte(s)) 10 | } 11 | 12 | func (c *Config) LoadTOML(data []byte) error { 13 | res := make(map[string]interface{}) 14 | if err := toml.Unmarshal(data, &res); err != nil { 15 | return err 16 | } 17 | return mergo.Merge(&c.Data, res, mergo.WithOverride) 18 | } 19 | -------------------------------------------------------------------------------- /str/case.go: -------------------------------------------------------------------------------- 1 | package str 2 | 3 | import ( 4 | "unicode" 5 | ) 6 | 7 | func ToSnakeCase(s string) string { 8 | runes := []rune(s) 9 | var result []rune 10 | for i := 0; i < len(runes); i++ { 11 | if i > 0 && 12 | unicode.IsUpper(runes[i]) && 13 | ((i+1 < len(runes) && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) { 14 | result = append(result, '_') 15 | } 16 | result = append(result, unicode.ToLower(runes[i])) 17 | } 18 | return string(result) 19 | } 20 | -------------------------------------------------------------------------------- /query/update_test.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestUpdate(t *testing.T) { 10 | stmt, args, err := NewUpdate(). 11 | Table("users"). 12 | Assign("name", "Bob"). 13 | Where(Equal("id", 42)). 14 | Build(DialectKindCassandra) 15 | 16 | assert.NoError(t, err) 17 | assert.Equal(t, "UPDATE users SET name = ? WHERE id = ?", stmt) 18 | assert.Equal(t, "Bob", args[0]) 19 | assert.Equal(t, 42, args[1]) 20 | } 21 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/forward_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | // Assertions provides assertion methods around the 4 | // TestingT interface. 5 | type Assertions struct { 6 | t TestingT 7 | } 8 | 9 | // New makes a new Assertions object for the specified TestingT. 10 | func New(t TestingT) *Assertions { 11 | return &Assertions{ 12 | t: t, 13 | } 14 | } 15 | 16 | //go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs 17 | -------------------------------------------------------------------------------- /query/insert_test.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestInsert(t *testing.T) { 10 | i := NewInsert(). 11 | Into("users"). 12 | Columns("name", "age"). 13 | Row("Bob", 20). 14 | Row("John", 24) 15 | 16 | stmt, args, err := i.Build(DialectKindCassandra) 17 | assert.NoError(t, err) 18 | 19 | assert.Equal(t, "INSERT INTO users(name, age) VALUES (?, ?), (?, ?)", stmt) 20 | assert.Equal(t, "Bob", args[0]) 21 | assert.Equal(t, 20, args[1]) 22 | assert.Equal(t, "John", args[2]) 23 | assert.Equal(t, 24, args[3]) 24 | } 25 | -------------------------------------------------------------------------------- /valid/validator.go: -------------------------------------------------------------------------------- 1 | package valid 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | var ( 8 | ErrIncompatibleTypes = errors.New("incompatible types") 9 | ) 10 | 11 | type Constraint func(value interface{}) error 12 | 13 | type Validator struct { 14 | constraints []Constraint 15 | } 16 | 17 | func New(constraints ...Constraint) *Validator { 18 | return &Validator{ 19 | constraints: constraints, 20 | } 21 | } 22 | 23 | func (v Validator) Validate(value interface{}) error { 24 | for _, c := range v.constraints { 25 | if err := c(value); err != nil { 26 | return err 27 | } 28 | } 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/encoding_types_1.1.go: -------------------------------------------------------------------------------- 1 | // +build !go1.2 2 | 3 | package toml 4 | 5 | // These interfaces were introduced in Go 1.2, so we add them manually when 6 | // compiling for Go 1.1. 7 | 8 | // TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here 9 | // so that Go 1.1 can be supported. 10 | type TextMarshaler interface { 11 | MarshalText() (text []byte, err error) 12 | } 13 | 14 | // TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined 15 | // here so that Go 1.1 can be supported. 16 | type TextUnmarshaler interface { 17 | UnmarshalText(text []byte) error 18 | } 19 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2011-2016 Canonical Ltd. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /valid/generic_test.go: -------------------------------------------------------------------------------- 1 | package valid 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestEqual(t *testing.T) { 10 | v := New( 11 | Equal(42), 12 | ) 13 | assert.NoError(t, v.Validate(42)) 14 | assert.Error(t, ErrNotEqual, v.Validate(42.0)) 15 | } 16 | 17 | func TestNil(t *testing.T) { 18 | v := New( 19 | Nil(), 20 | ) 21 | assert.NoError(t, v.Validate(nil)) 22 | assert.Error(t, ErrNotNil, v.Validate(42)) 23 | } 24 | 25 | func TestNotNil(t *testing.T) { 26 | v := New( 27 | NotNil(), 28 | ) 29 | assert.NoError(t, v.Validate(42)) 30 | assert.Error(t, ErrNil, v.Validate(nil)) 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/encoding_types.go: -------------------------------------------------------------------------------- 1 | // +build go1.2 2 | 3 | package toml 4 | 5 | // In order to support Go 1.1, we define our own TextMarshaler and 6 | // TextUnmarshaler types. For Go 1.2+, we just alias them with the 7 | // standard library interfaces. 8 | 9 | import ( 10 | "encoding" 11 | ) 12 | 13 | // TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here 14 | // so that Go 1.1 can be supported. 15 | type TextMarshaler encoding.TextMarshaler 16 | 17 | // TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined 18 | // here so that Go 1.1 can be supported. 19 | type TextUnmarshaler encoding.TextUnmarshaler 20 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/.gitignore: -------------------------------------------------------------------------------- 1 | #### joe made this: http://goel.io/joe 2 | 3 | #### go #### 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | # Test binary, build with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 17 | .glide/ 18 | 19 | #### vim #### 20 | # Swap 21 | [._]*.s[a-v][a-z] 22 | [._]*.sw[a-p] 23 | [._]s[a-v][a-z] 24 | [._]sw[a-p] 25 | 26 | # Session 27 | Session.vim 28 | 29 | # Temporary 30 | .netrwhist 31 | *~ 32 | # Auto-generated tag files 33 | tags 34 | -------------------------------------------------------------------------------- /vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/BurntSushi/toml v0.3.1 2 | github.com/BurntSushi/toml 3 | # github.com/davecgh/go-spew v1.1.0 4 | github.com/davecgh/go-spew/spew 5 | # github.com/imdario/mergo v0.3.7 6 | github.com/imdario/mergo 7 | # github.com/mitchellh/mapstructure v1.1.2 8 | github.com/mitchellh/mapstructure 9 | # github.com/pkg/errors v0.8.1 10 | github.com/pkg/errors 11 | # github.com/pmezard/go-difflib v1.0.0 12 | github.com/pmezard/go-difflib/difflib 13 | # github.com/stretchr/testify v1.3.0 14 | github.com/stretchr/testify/assert 15 | # golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c 16 | golang.org/x/crypto/scrypt 17 | golang.org/x/crypto/pbkdf2 18 | # gopkg.in/yaml.v2 v2.2.2 19 | gopkg.in/yaml.v2 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kit 2 | 3 | [![Build Status](https://travis-ci.org/tinrab/kit.svg?branch=master)](https://travis-ci.org/tinrab/kit) 4 | 5 | A collection of utilities. 6 | 7 | ## Utilities 8 | 9 | - Dependency Injection ([source](./di), [examples](./di/di_test.go)) 10 | - Security ([source](./security)) 11 | - Retry ([source](./retry), [examples](./retry/retry_test.go)) 12 | - Config ([source](./cfg), [examples](./cfg/cfg_test.go)) 13 | - Unique IDs ([source](./id), [examples](./id/id_test.go)) 14 | - Query ([query examples](./query/query_test.go), [insert examples](./query/insert_test.go), [update examples](./query/update_test.go)) 15 | - Validators ([source](./valid), [examples](./valid/validator_test.go)) 16 | - String utils ([str](./str)) 17 | -------------------------------------------------------------------------------- /valid/generic.go: -------------------------------------------------------------------------------- 1 | package valid 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | var ( 8 | ErrNotEqual = errors.New("values are not equal") 9 | ErrNotNil = errors.New("value is not nil") 10 | ErrNil = errors.New("value is nil") 11 | ) 12 | 13 | func Equal(value interface{}) Constraint { 14 | return func(v interface{}) error { 15 | if v != value { 16 | return ErrNotEqual 17 | } 18 | return nil 19 | } 20 | } 21 | 22 | func Nil() Constraint { 23 | return func(value interface{}) error { 24 | if value != nil { 25 | return ErrNotNil 26 | } 27 | return nil 28 | } 29 | } 30 | 31 | func NotNil() Constraint { 32 | return func(value interface{}) error { 33 | if value == nil { 34 | return ErrNil 35 | } 36 | return nil 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.1.2 2 | 3 | * Fix error when decode hook decodes interface implementation into interface 4 | type. [GH-140] 5 | 6 | ## 1.1.1 7 | 8 | * Fix panic that can happen in `decodePtr` 9 | 10 | ## 1.1.0 11 | 12 | * Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133] 13 | * Support struct to struct decoding [GH-137] 14 | * If source map value is nil, then destination map value is nil (instead of empty) 15 | * If source slice value is nil, then destination slice value is nil (instead of empty) 16 | * If source pointer is nil, then destination pointer is set to nil (instead of 17 | allocated zero value of type) 18 | 19 | ## 1.0.0 20 | 21 | * Initial tagged stable release. 22 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/writerc.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | // Set the writer error and return false. 4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { 5 | emitter.error = yaml_WRITER_ERROR 6 | emitter.problem = problem 7 | return false 8 | } 9 | 10 | // Flush the output buffer. 11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool { 12 | if emitter.write_handler == nil { 13 | panic("write handler not set") 14 | } 15 | 16 | // Check if the buffer is empty. 17 | if emitter.buffer_pos == 0 { 18 | return true 19 | } 20 | 21 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { 22 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 23 | } 24 | emitter.buffer_pos = 0 25 | return true 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: build-{build}.{branch} 2 | 3 | clone_folder: C:\gopath\src\github.com\pkg\errors 4 | shallow_clone: true # for startup speed 5 | 6 | environment: 7 | GOPATH: C:\gopath 8 | 9 | platform: 10 | - x64 11 | 12 | # http://www.appveyor.com/docs/installed-software 13 | install: 14 | # some helpful output for debugging builds 15 | - go version 16 | - go env 17 | # pre-installed MinGW at C:\MinGW is 32bit only 18 | # but MSYS2 at C:\msys64 has mingw64 19 | - set PATH=C:\msys64\mingw64\bin;%PATH% 20 | - gcc --version 21 | - g++ --version 22 | 23 | build_script: 24 | - go install -v ./... 25 | 26 | test_script: 27 | - set PATH=C:\gopath\bin;%PATH% 28 | - go test -v ./... 29 | 30 | #artifacts: 31 | # - path: '%GOPATH%\bin\*.exe' 32 | deploy: off 33 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2012-2016 Dave Collins 4 | 5 | Permission to use, copy, modify, and distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /expr/expr.go: -------------------------------------------------------------------------------- 1 | package expr 2 | 3 | import ( 4 | "go/ast" 5 | "go/parser" 6 | ) 7 | 8 | // Expression 9 | type Expression struct { 10 | Source string 11 | tree ast.Expr 12 | } 13 | 14 | func New(source string) *Expression { 15 | return &Expression{ 16 | Source: source, 17 | } 18 | } 19 | 20 | func (e *Expression) Parse() error { 21 | tree, err := parser.ParseExpr(e.Source) 22 | if err != nil { 23 | return err 24 | } 25 | e.tree = tree 26 | return nil 27 | } 28 | 29 | func (e *Expression) Evaluate() (interface{}, error) { 30 | if e.tree == nil { 31 | err := e.Parse() 32 | if err != nil { 33 | return false, err 34 | } 35 | } 36 | eval := newEvaluator() 37 | return eval.Evaluate(e.tree) 38 | } 39 | 40 | func (e *Expression) MustEvaluate() (interface{}) { 41 | res, err := e.Evaluate() 42 | if err != nil { 43 | panic(err) 44 | } 45 | return res 46 | } 47 | -------------------------------------------------------------------------------- /query/query_test.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestQuery(t *testing.T) { 10 | stmt, args, err := NewQuery(). 11 | From("users"). 12 | Columns("name", "created_at", "age"). 13 | Where(Equal("name", "Bob")). 14 | Take(1). 15 | Build(DialectKindCassandra) 16 | assert.NoError(t, err) 17 | 18 | assert.Equal(t, "SELECT name, created_at, age FROM users WHERE name = ? LIMIT 1 ALLOW FILTERING", stmt) 19 | assert.Equal(t, "Bob", args[0]) 20 | } 21 | 22 | func TestInQuery(t *testing.T) { 23 | stmt, args, err := NewQuery(). 24 | From("users"). 25 | Columns("name"). 26 | Where(In("id", []interface{}{10, 20, 50})). 27 | Build(DialectKindCassandra) 28 | assert.NoError(t, err) 29 | 30 | assert.Equal(t, "SELECT name FROM users WHERE id IN (?, ?, ?) LIMIT 0 ALLOW FILTERING", stmt) 31 | assert.EqualValues(t, []interface{}{10, 20, 50}, args) 32 | } 33 | -------------------------------------------------------------------------------- /expr/stack.go: -------------------------------------------------------------------------------- 1 | package expr 2 | 3 | type Stack struct { 4 | items []interface{} 5 | } 6 | 7 | func NewStack() *Stack { 8 | return &Stack{ 9 | items: []interface{}{}, 10 | } 11 | } 12 | 13 | func (s *Stack) Size() int { 14 | return len(s.items) 15 | } 16 | 17 | func (s *Stack) IsEmpty() bool { 18 | return s.Size() == 0 19 | } 20 | 21 | func (s *Stack) Clear() { 22 | s.items = []interface{}{} 23 | } 24 | 25 | func (s *Stack) Push(item interface{}) { 26 | s.items = append(s.items, item) 27 | } 28 | 29 | func (s *Stack) Pop() interface{} { 30 | if s.IsEmpty() { 31 | panic("stack is empty") 32 | } 33 | item := s.items[s.Size()-1] 34 | s.items = s.items[:s.Size()-1] 35 | return item 36 | } 37 | 38 | func (s *Stack) Head() interface{} { 39 | if s.IsEmpty() { 40 | panic("stack is empty") 41 | } 42 | return s.items[s.Size()-1] 43 | } 44 | 45 | func (s *Stack) Tail() interface{} { 46 | if s.Size() == 0 { 47 | panic("stack is empty") 48 | } 49 | return s.items[0] 50 | } 51 | -------------------------------------------------------------------------------- /query/insert.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | type Insert struct { 4 | into string 5 | columns []string 6 | rows [][]interface{} 7 | } 8 | 9 | func NewInsert() *Insert { 10 | return &Insert{ 11 | columns: make([]string, 0), 12 | rows: make([][]interface{}, 0), 13 | } 14 | } 15 | 16 | func (i *Insert) Into(into string) *Insert { 17 | i.into = into 18 | return i 19 | } 20 | 21 | func (i *Insert) Columns(columns ...string) *Insert { 22 | i.columns = columns 23 | return i 24 | } 25 | 26 | func (i *Insert) Rows(rows ...[]interface{}) *Insert { 27 | i.rows = rows 28 | return i 29 | } 30 | 31 | func (i *Insert) Row(values ...interface{}) *Insert { 32 | i.rows = append(i.rows, values) 33 | return i 34 | } 35 | 36 | func (i Insert) Build(dialectKind DialectKind) (string, []interface{}, error) { 37 | var d dialect 38 | switch dialectKind { 39 | case DialectKindCassandra: 40 | d = &cassandraDialect{} 41 | } 42 | if d == nil { 43 | return "", nil, ErrInvalidDialect 44 | } 45 | return d.BuildInsert(i) 46 | } 47 | -------------------------------------------------------------------------------- /retry/retry_test.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestRetry(t *testing.T) { 10 | err := Retry(4, func(attempt int) (err error) { 11 | if attempt < 3 { 12 | err = errors.New("") 13 | } 14 | return err 15 | }) 16 | if err != nil { 17 | t.Fail() 18 | } 19 | } 20 | 21 | func TestRetryError(t *testing.T) { 22 | err := Retry(4, func(attempt int) error { 23 | return errors.New("") 24 | }) 25 | if err == nil { 26 | t.Fail() 27 | } 28 | } 29 | 30 | func TestRetrySleep(t *testing.T) { 31 | startTime := time.Now().UnixNano() 32 | sleepTime := 200 * time.Millisecond 33 | 34 | err := Sleep(2, sleepTime, func(attempt int) (err error) { 35 | if attempt == 0 { 36 | err = errors.New("") 37 | } 38 | return err 39 | }) 40 | 41 | dt := (time.Now().UnixNano() - startTime - int64(sleepTime)) / (int64(time.Millisecond) / int64(time.Nanosecond)) 42 | maxErr := int64(50) 43 | if err != nil || (dt < -maxErr || dt > maxErr) { 44 | t.Fail() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /query/query.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | type Query struct { 4 | from string 5 | columns []string 6 | conditions []*Condition 7 | take int 8 | skip int 9 | } 10 | 11 | func NewQuery() *Query { 12 | return &Query{} 13 | } 14 | 15 | func (q *Query) From(from string) *Query { 16 | q.from = from 17 | return q 18 | } 19 | 20 | func (q *Query) Columns(columns ...string) *Query { 21 | q.columns = columns 22 | return q 23 | } 24 | 25 | func (q *Query) Where(conditions ...*Condition) *Query { 26 | q.conditions = append(q.conditions, conditions...) 27 | return q 28 | } 29 | 30 | func (q *Query) Take(take int) *Query { 31 | q.take = take 32 | return q 33 | } 34 | 35 | func (q *Query) Skip(skip int) *Query { 36 | q.skip = skip 37 | return q 38 | } 39 | 40 | func (q Query) Build(dialectKind DialectKind) (string, []interface{}, error) { 41 | var d dialect 42 | switch dialectKind { 43 | case DialectKindCassandra: 44 | d = &cassandraDialect{} 45 | } 46 | if d == nil { 47 | return "", nil, ErrInvalidDialect 48 | } 49 | return d.BuildQuery(q) 50 | } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tin Rabzelj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /query/update.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | type Update struct { 4 | table string 5 | assignments []Assignment 6 | conditions []*Condition 7 | } 8 | 9 | type Assignment struct { 10 | Column string 11 | Value interface{} 12 | } 13 | 14 | func NewUpdate() *Update { 15 | return &Update{ 16 | assignments: make([]Assignment, 0), 17 | conditions: make([]*Condition, 0), 18 | } 19 | } 20 | 21 | func (u *Update) Table(table string) *Update { 22 | u.table = table 23 | return u 24 | } 25 | 26 | func (u *Update) Assign(column string, value interface{}) *Update { 27 | u.assignments = append(u.assignments, Assignment{ 28 | Column: column, 29 | Value: value, 30 | }) 31 | return u 32 | } 33 | 34 | func (u *Update) Where(conditions ...*Condition) *Update { 35 | u.conditions = append(u.conditions, conditions...) 36 | return u 37 | } 38 | 39 | func (u Update) Build(dialectKind DialectKind) (string, []interface{}, error) { 40 | var d dialect 41 | switch dialectKind { 42 | case DialectKindCassandra: 43 | d = &cassandraDialect{} 44 | } 45 | if d == nil { 46 | return "", nil, ErrInvalidDialect 47 | } 48 | return d.BuildUpdate(u) 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/COPYING: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 TOML authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Dario Castañé. All rights reserved. 2 | // Copyright 2009 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | /* 7 | Package mergo merges same-type structs and maps by setting default values in zero-value fields. 8 | 9 | Mergo won't merge unexported (private) fields but will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection). 10 | 11 | Usage 12 | 13 | From my own work-in-progress project: 14 | 15 | type networkConfig struct { 16 | Protocol string 17 | Address string 18 | ServerType string `json: "server_type"` 19 | Port uint16 20 | } 21 | 22 | type FssnConfig struct { 23 | Network networkConfig 24 | } 25 | 26 | var fssnDefault = FssnConfig { 27 | networkConfig { 28 | "tcp", 29 | "127.0.0.1", 30 | "http", 31 | 31560, 32 | }, 33 | } 34 | 35 | // Inside a function [...] 36 | 37 | if err := mergo.Merge(&config, fssnDefault); err != nil { 38 | log.Fatal(err) 39 | } 40 | 41 | // More code [...] 42 | 43 | */ 44 | package mergo 45 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Mitchell Hashimoto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /retry/retry.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Func func(int) error 8 | 9 | // Retry retries calling function f n-times. 10 | // It returns an error if none of the tries succeeds. 11 | func Retry(n int, f Func) (err error) { 12 | for i := 0; i < n; i++ { 13 | err = f(i) 14 | if err == nil { 15 | return nil 16 | } 17 | } 18 | return err 19 | } 20 | 21 | // Sleep retries calling function f n-times and sleeps for d after each call. 22 | // It returns an error if none of the tries succeeds. 23 | func Sleep(n int, d time.Duration, f Func) (err error) { 24 | for i := 0; i < n; i++ { 25 | err = f(i) 26 | if err == nil { 27 | return nil 28 | } 29 | time.Sleep(d) 30 | } 31 | return err 32 | } 33 | 34 | // RetryForever keeps trying to call function f until it succeeds. 35 | func Forever(f Func) { 36 | for i := 0; ; i++ { 37 | err := f(i) 38 | if err == nil { 39 | return 40 | } 41 | } 42 | } 43 | 44 | // RetryForeverSleep keeps trying to call function f until it succeeds, and sleeps after each failure. 45 | func ForeverSleep(d time.Duration, f Func) { 46 | for i := 0; ; i++ { 47 | err := f(i) 48 | if err == nil { 49 | return 50 | } 51 | time.Sleep(d) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package toml provides facilities for decoding and encoding TOML configuration 3 | files via reflection. There is also support for delaying decoding with 4 | the Primitive type, and querying the set of keys in a TOML document with the 5 | MetaData type. 6 | 7 | The specification implemented: https://github.com/toml-lang/toml 8 | 9 | The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify 10 | whether a file is a valid TOML document. It can also be used to print the 11 | type of each key in a TOML document. 12 | 13 | Testing 14 | 15 | There are two important types of tests used for this package. The first is 16 | contained inside '*_test.go' files and uses the standard Go unit testing 17 | framework. These tests are primarily devoted to holistically testing the 18 | decoder and encoder. 19 | 20 | The second type of testing is used to verify the implementation's adherence 21 | to the TOML specification. These tests have been factored into their own 22 | project: https://github.com/BurntSushi/toml-test 23 | 24 | The reason the tests are in a separate project is so that they can be used by 25 | any implementation of TOML. Namely, it is language agnostic. 26 | */ 27 | package toml 28 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/error.go: -------------------------------------------------------------------------------- 1 | package mapstructure 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "sort" 7 | "strings" 8 | ) 9 | 10 | // Error implements the error interface and can represents multiple 11 | // errors that occur in the course of a single decode. 12 | type Error struct { 13 | Errors []string 14 | } 15 | 16 | func (e *Error) Error() string { 17 | points := make([]string, len(e.Errors)) 18 | for i, err := range e.Errors { 19 | points[i] = fmt.Sprintf("* %s", err) 20 | } 21 | 22 | sort.Strings(points) 23 | return fmt.Sprintf( 24 | "%d error(s) decoding:\n\n%s", 25 | len(e.Errors), strings.Join(points, "\n")) 26 | } 27 | 28 | // WrappedErrors implements the errwrap.Wrapper interface to make this 29 | // return value more useful with the errwrap and go-multierror libraries. 30 | func (e *Error) WrappedErrors() []error { 31 | if e == nil { 32 | return nil 33 | } 34 | 35 | result := make([]error, len(e.Errors)) 36 | for i, e := range e.Errors { 37 | result[i] = errors.New(e) 38 | } 39 | 40 | return result 41 | } 42 | 43 | func appendErrors(errors []string, err error) []string { 44 | switch e := err.(type) { 45 | case *Error: 46 | return append(errors, e.Errors...) 47 | default: 48 | return append(errors, e.Error()) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /valid/number.go: -------------------------------------------------------------------------------- 1 | package valid 2 | 3 | import ( 4 | "errors" 5 | "reflect" 6 | ) 7 | 8 | var ( 9 | ErrNumberOutOfRange = errors.New("number is out of range") 10 | ) 11 | 12 | func Range(min interface{}, max interface{}) Constraint { 13 | return func(value interface{}) error { 14 | valid := true 15 | 16 | if reflect.TypeOf(min) != reflect.TypeOf(max) || reflect.TypeOf(min) != reflect.TypeOf(value) { 17 | return ErrIncompatibleTypes 18 | } 19 | 20 | switch v := value.(type) { 21 | case int: 22 | valid = v >= min.(int) && v <= max.(int) 23 | case int8: 24 | valid = v >= min.(int8) && v <= max.(int8) 25 | case int16: 26 | valid = v >= min.(int16) && v <= max.(int16) 27 | case int32: 28 | valid = v >= min.(int32) && v <= max.(int32) 29 | case int64: 30 | valid = v >= min.(int64) && v <= max.(int64) 31 | case uint8: 32 | valid = v >= min.(uint8) && v <= max.(uint8) 33 | case uint16: 34 | valid = v >= min.(uint16) && v <= max.(uint16) 35 | case uint32: 36 | valid = v >= min.(uint32) && v <= max.(uint32) 37 | case uint64: 38 | valid = v >= min.(uint64) && v <= max.(uint64) 39 | case float32: 40 | valid = v >= min.(float32) && v <= max.(float32) 41 | case float64: 42 | valid = v >= min.(float64) && v <= max.(float64) 43 | } 44 | 45 | if !valid { 46 | return ErrNumberOutOfRange 47 | } 48 | return nil 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /cfg/cfg.go: -------------------------------------------------------------------------------- 1 | package cfg 2 | 3 | import ( 4 | "io/ioutil" 5 | "path/filepath" 6 | 7 | "github.com/mitchellh/mapstructure" 8 | ) 9 | 10 | type Config struct { 11 | Data map[string]interface{} 12 | } 13 | 14 | func New() *Config { 15 | return &Config{ 16 | Data: make(map[string]interface{}), 17 | } 18 | } 19 | 20 | func (c *Config) LoadGlob(pattern string) error { 21 | files, err := filepath.Glob(pattern) 22 | if err != nil { 23 | return err 24 | } 25 | for _, filename := range files { 26 | err = c.LoadFile(filename) 27 | if err != nil { 28 | return err 29 | } 30 | } 31 | return nil 32 | } 33 | 34 | func (c *Config) LoadFile(filename string) error { 35 | data, err := ioutil.ReadFile(filename) 36 | if err != nil { 37 | return err 38 | } 39 | ext := filepath.Ext(filename) 40 | if ext == ".yml" || ext == ".yaml" { 41 | return c.LoadYAML(data) 42 | } else if ext == ".json" { 43 | return c.LoadJSON(data) 44 | } 45 | return nil 46 | } 47 | 48 | func (c *Config) Decode(out interface{}) error { 49 | d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ 50 | TagName: "cfg", 51 | WeaklyTypedInput: true, 52 | Result: out, 53 | DecodeHook: mapstructure.ComposeDecodeHookFunc( 54 | mapstructure.StringToTimeDurationHookFunc(), 55 | ), 56 | }) 57 | if err != nil { 58 | return err 59 | } 60 | return d.Decode(c.Data) 61 | } 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Dave Cheney 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /expr/expr_test.go: -------------------------------------------------------------------------------- 1 | package expr 2 | 3 | import ( 4 | "testing" 5 | "github.com/stretchr/testify/assert" 6 | "math" 7 | ) 8 | 9 | func TestBinary(t *testing.T) { 10 | assert.Equal(t, 2.0, New("1 + 1").MustEvaluate()) 11 | assert.Equal(t, 2.0, New("3 - 1").MustEvaluate()) 12 | assert.Equal(t, 4.0, New("2 * 2").MustEvaluate()) 13 | assert.Equal(t, 2.0, New("4 / 2").MustEvaluate()) 14 | } 15 | 16 | func TestCompound(t *testing.T) { 17 | assert.Equal(t, 2.0, New("4 * 2 / 4").MustEvaluate()) 18 | assert.Equal(t, 4.0, New("(1+1)*2/(2-1)").MustEvaluate()) 19 | } 20 | 21 | func TestFunc(t *testing.T) { 22 | assert.Equal(t, math.Pi, New("Pi").MustEvaluate()) 23 | assert.Equal(t, math.E, New("E").MustEvaluate()) 24 | assert.Equal(t, 3.0, New("floor(3.5)").MustEvaluate()) 25 | assert.Equal(t, 3.0, New("round(3.49)").MustEvaluate()) 26 | assert.Equal(t, 4.0, New("ceil(3.5)").MustEvaluate()) 27 | assert.Equal(t, 8.0, New("pow(2, 3)").MustEvaluate()) 28 | } 29 | 30 | func TestBool(t *testing.T) { 31 | assert.True(t, New("true").MustEvaluate().(bool)) 32 | assert.False(t, New("false").MustEvaluate().(bool)) 33 | assert.True(t, New("2 == 2").MustEvaluate().(bool)) 34 | assert.False(t, New("2 == 3").MustEvaluate().(bool)) 35 | } 36 | 37 | func TestUnary(t *testing.T) { 38 | assert.Equal(t, -3.0, New("-3").MustEvaluate().(float64)) 39 | assert.True(t, New("!false").MustEvaluate().(bool)) 40 | assert.True(t, New("3 == (2 + 1)").MustEvaluate().(bool)) 41 | } 42 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/LICENSE.libyaml: -------------------------------------------------------------------------------- 1 | The following files were ported to Go from C files of libyaml, and thus 2 | are still covered by their original copyright and license: 3 | 4 | apic.go 5 | emitterc.go 6 | parserc.go 7 | readerc.go 8 | scannerc.go 9 | writerc.go 10 | yamlh.go 11 | yamlprivateh.go 12 | 13 | Copyright (c) 2006 Kirill Simonov 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of 16 | this software and associated documentation files (the "Software"), to deal in 17 | the Software without restriction, including without limitation the rights to 18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 19 | of the Software, and to permit persons to whom the Software is furnished to do 20 | so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | -------------------------------------------------------------------------------- /di/di_test.go: -------------------------------------------------------------------------------- 1 | package di 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | type Database interface { 10 | GetValue() int 11 | } 12 | 13 | type databaseImpl struct { 14 | Started bool 15 | } 16 | 17 | func (d *databaseImpl) GetValue() int { 18 | return 42 19 | } 20 | 21 | func (d *databaseImpl) Open() error { 22 | d.Started = true 23 | return nil 24 | } 25 | 26 | func (d *databaseImpl) Close() { 27 | } 28 | 29 | type service struct { 30 | Database Database `inject:"db"` 31 | Started bool 32 | } 33 | 34 | func (s *service) Open() error { 35 | s.Started = true 36 | return nil 37 | } 38 | 39 | func (s *service) Close() { 40 | } 41 | 42 | func TestDependencyInjection(t *testing.T) { 43 | c := New() 44 | c.Provide("db", &databaseImpl{}) 45 | c.Provide("s", &service{}) 46 | 47 | assert.NoError(t, c.Resolve()) 48 | 49 | db, _ := c.GetByName("db").(*databaseImpl) 50 | assert.True(t, db.Started) 51 | s, _ := c.GetByName("s").(*service) 52 | assert.True(t, s.Started) 53 | assert.Equal(t, 42, s.Database.GetValue()) 54 | } 55 | 56 | type A struct { 57 | B *B 58 | } 59 | 60 | func (a *A) Value() int { 61 | return a.B.Value() 62 | } 63 | 64 | type B struct { 65 | } 66 | 67 | func (b *B) Value() int { 68 | return 42 69 | } 70 | 71 | func TestWithStruct(t *testing.T) { 72 | c := New() 73 | c.Provide("a", &A{}) 74 | c.Provide("b", &B{}) 75 | assert.NoError(t, c.Resolve()) 76 | 77 | a := c.GetByType(&A{}).(*A) 78 | assert.NotNil(t, a.B) 79 | assert.Equal(t, 42, a.Value()) 80 | } 81 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Patrick Mezard 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | The names of its contributors may not be used to endorse or promote 14 | products derived from this software without specific prior written 15 | permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/doc.go: -------------------------------------------------------------------------------- 1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. 2 | // 3 | // Example Usage 4 | // 5 | // The following is a complete example using assert in a standard test function: 6 | // import ( 7 | // "testing" 8 | // "github.com/stretchr/testify/assert" 9 | // ) 10 | // 11 | // func TestSomething(t *testing.T) { 12 | // 13 | // var a string = "Hello" 14 | // var b string = "Hello" 15 | // 16 | // assert.Equal(t, a, b, "The two words should be the same.") 17 | // 18 | // } 19 | // 20 | // if you assert many times, use the format below: 21 | // 22 | // import ( 23 | // "testing" 24 | // "github.com/stretchr/testify/assert" 25 | // ) 26 | // 27 | // func TestSomething(t *testing.T) { 28 | // assert := assert.New(t) 29 | // 30 | // var a string = "Hello" 31 | // var b string = "Hello" 32 | // 33 | // assert.Equal(a, b, "The two words should be the same.") 34 | // } 35 | // 36 | // Assertions 37 | // 38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package. 39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the 40 | // testing framework. This allows the assertion funcs to write the failings and other details to 41 | // the correct place. 42 | // 43 | // Every assertion function also takes an optional string message as the final argument, 44 | // allowing custom error messages to be appended to the message the assertion method outputs. 45 | package assert 46 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Dario Castañé. All rights reserved. 2 | Copyright (c) 2012 The Go Authors. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/README.md: -------------------------------------------------------------------------------- 1 | # mapstructure [![Godoc](https://godoc.org/github.com/mitchellh/mapstructure?status.svg)](https://godoc.org/github.com/mitchellh/mapstructure) 2 | 3 | mapstructure is a Go library for decoding generic map values to structures 4 | and vice versa, while providing helpful error handling. 5 | 6 | This library is most useful when decoding values from some data stream (JSON, 7 | Gob, etc.) where you don't _quite_ know the structure of the underlying data 8 | until you read a part of it. You can therefore read a `map[string]interface{}` 9 | and use this library to decode it into the proper underlying native Go 10 | structure. 11 | 12 | ## Installation 13 | 14 | Standard `go get`: 15 | 16 | ``` 17 | $ go get github.com/mitchellh/mapstructure 18 | ``` 19 | 20 | ## Usage & Example 21 | 22 | For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure). 23 | 24 | The `Decode` function has examples associated with it there. 25 | 26 | ## But Why?! 27 | 28 | Go offers fantastic standard libraries for decoding formats such as JSON. 29 | The standard method is to have a struct pre-created, and populate that struct 30 | from the bytes of the encoded format. This is great, but the problem is if 31 | you have configuration or an encoding that changes slightly depending on 32 | specific fields. For example, consider this JSON: 33 | 34 | ```json 35 | { 36 | "type": "person", 37 | "name": "Mitchell" 38 | } 39 | ``` 40 | 41 | Perhaps we can't populate a specific structure without first reading 42 | the "type" field from the JSON. We could always do two passes over the 43 | decoding of the JSON (reading the "type" first, and the rest later). 44 | However, it is much simpler to just decode this into a `map[string]interface{}` 45 | structure, read the "type" key, then use something like this library 46 | to decode it into the proper structure. 47 | -------------------------------------------------------------------------------- /cfg/cfg_test.go: -------------------------------------------------------------------------------- 1 | package cfg 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | "time" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | type config struct { 12 | Name string `cfg:"name"` 13 | Service serviceConfig `cfg:"service"` 14 | } 15 | 16 | type serviceConfig struct { 17 | Port uint16 `cfg:"port"` 18 | Timeout time.Duration `cfg:"timeout"` 19 | IDs []uint64 `cfg:"ids"` 20 | Factor float32 `cfg:"factor"` 21 | } 22 | 23 | func TestGlob(t *testing.T) { 24 | c := New() 25 | assert.NoError(t, c.LoadGlob("./*")) 26 | 27 | d := config{} 28 | assert.NoError(t, c.Decode(&d)) 29 | expected := config{ 30 | Name: "App", 31 | Service: serviceConfig{ 32 | Port: 4200, 33 | Timeout: 5 * time.Second, 34 | IDs: []uint64{1, 2, 42}, 35 | Factor: 3.14, 36 | }, 37 | } 38 | assert.True(t, reflect.DeepEqual(expected, d)) 39 | } 40 | 41 | func TestJSON(t *testing.T) { 42 | c := New() 43 | assert.NoError(t, c.LoadJSONString(`{ 44 | "name": "App", 45 | "service": { 46 | "port": 4200, 47 | "ids": [1, 2, 42], 48 | "factor": 3.14 49 | } 50 | }`)) 51 | 52 | d := config{} 53 | assert.NoError(t, c.Decode(&d)) 54 | expected := config{ 55 | Name: "App", 56 | Service: serviceConfig{ 57 | Port: 4200, 58 | IDs: []uint64{1, 2, 42}, 59 | Factor: 3.14, 60 | }, 61 | } 62 | assert.True(t, reflect.DeepEqual(expected, d)) 63 | } 64 | 65 | func TestYAML(t *testing.T) { 66 | c := New() 67 | assert.NoError(t, c.LoadYAMLString(` 68 | name: "App" 69 | service: 70 | port: 4200 71 | ids: [1, 2, 42] 72 | factor: 3.14 73 | `)) 74 | 75 | d := config{} 76 | assert.NoError(t, c.Decode(&d)) 77 | expected := config{ 78 | Name: "App", 79 | Service: serviceConfig{ 80 | Port: 4200, 81 | IDs: []uint64{1, 2, 42}, 82 | Factor: 3.14, 83 | }, 84 | } 85 | assert.True(t, reflect.DeepEqual(expected, d)) 86 | } 87 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypasssafe.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is running on Google App Engine, compiled by GopherJS, or 17 | // "-tags safe" is added to the go build command line. The "disableunsafe" 18 | // tag is deprecated and thus should not be used. 19 | // +build js appengine safe disableunsafe 20 | 21 | package spew 22 | 23 | import "reflect" 24 | 25 | const ( 26 | // UnsafeDisabled is a build-time constant which specifies whether or 27 | // not access to the unsafe package is available. 28 | UnsafeDisabled = true 29 | ) 30 | 31 | // unsafeReflectValue typically converts the passed reflect.Value into a one 32 | // that bypasses the typical safety restrictions preventing access to 33 | // unaddressable and unexported data. However, doing this relies on access to 34 | // the unsafe package. This is a stub version which simply returns the passed 35 | // reflect.Value when the unsafe package is not available. 36 | func unsafeReflectValue(v reflect.Value) reflect.Value { 37 | return v 38 | } 39 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= 6 | github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 7 | github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= 8 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 9 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 10 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 11 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 12 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 13 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 14 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 15 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 16 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= 17 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 18 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 19 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 20 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 21 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 22 | -------------------------------------------------------------------------------- /id/id_test.go: -------------------------------------------------------------------------------- 1 | package id 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | type Cat struct { 11 | ID ID `json:"id"` 12 | Name string `json:"name"` 13 | } 14 | 15 | func TestParse(t *testing.T) { 16 | i, err := Parse("6604873748002701312") 17 | assert.NoError(t, err) 18 | assert.Equal(t, ID(6604873748002701312), i) 19 | } 20 | 21 | func TestJSON(t *testing.T) { 22 | g := NewGenerator(1) 23 | 24 | i := g.Generate() 25 | cat := Cat{ 26 | ID: i, 27 | Name: "John", 28 | } 29 | js, err := json.Marshal(cat) 30 | assert.NoError(t, err) 31 | 32 | decodedCat := &Cat{} 33 | assert.NoError(t, json.Unmarshal(js, decodedCat)) 34 | 35 | assert.Equal(t, cat.Name, decodedCat.Name) 36 | assert.Equal(t, i, decodedCat.ID) 37 | } 38 | 39 | func TestGenerate(t *testing.T) { 40 | g := NewGenerator(42) 41 | 42 | var ids []ID 43 | 44 | for i := 0; i < 10; i++ { 45 | id := g.Generate() 46 | for _, x := range ids { 47 | if x == id { 48 | t.Fail() 49 | } 50 | } 51 | ids = append(ids, id) 52 | } 53 | } 54 | 55 | func TestGenerateList(t *testing.T) { 56 | g := NewGenerator(42) 57 | const n = 1026 58 | 59 | ids := g.GenerateList(n) 60 | 61 | assert.Equal(t, n, len(ids)) 62 | 63 | for i, x := range ids { 64 | if i == 0 { 65 | continue 66 | } 67 | 68 | for _, y := range ids[:i] { 69 | if y == x { 70 | t.Fatal("generated duplicate IDs") 71 | } 72 | } 73 | } 74 | } 75 | 76 | func TestBase64(t *testing.T) { 77 | ids := []ID{ 78 | 42, 1337, 932568, 79 | } 80 | for i, id := range ids { 81 | v := id.Base64() 82 | v2, err := ParseBase64(v) 83 | if err != nil { 84 | t.Fatal(err) 85 | } 86 | 87 | assert.Equal(t, ids[i], v2) 88 | } 89 | } 90 | 91 | func TestBase62(t *testing.T) { 92 | ids := []ID{ 93 | 13, 1337, 13333333337, 94 | } 95 | for i, id := range ids { 96 | v := id.Base62() 97 | v2, err := ParseBase62(v) 98 | if err != nil { 99 | t.Fatal(err) 100 | } 101 | 102 | assert.Equal(t, ids[i], v2) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /query/operator.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | type Operator uint8 4 | 5 | const ( 6 | OperatorAnd Operator = iota 7 | OperatorOr Operator = iota 8 | OperatorEqual Operator = iota 9 | OperatorNotEqual Operator = iota 10 | OperatorGreater Operator = iota 11 | OperatorLess Operator = iota 12 | OperatorGreaterOrEqual Operator = iota 13 | OperatorLessOrEqual Operator = iota 14 | OperatorIn Operator = iota 15 | ) 16 | 17 | type Condition struct { 18 | Operation Operator 19 | Left interface{} 20 | Right interface{} 21 | } 22 | 23 | func And(left *Condition, right *Condition) *Condition { 24 | return &Condition{ 25 | Operation: OperatorAnd, 26 | Left: left, 27 | Right: right, 28 | } 29 | } 30 | 31 | func Or(left *Condition, right *Condition) *Condition { 32 | return &Condition{ 33 | Operation: OperatorOr, 34 | Left: left, 35 | Right: right, 36 | } 37 | } 38 | 39 | func Equal(column string, value interface{}) *Condition { 40 | return &Condition{ 41 | Operation: OperatorEqual, 42 | Left: column, 43 | Right: value, 44 | } 45 | } 46 | 47 | func NotEqual(column string, value interface{}) *Condition { 48 | return &Condition{ 49 | Operation: OperatorNotEqual, 50 | Left: column, 51 | Right: value, 52 | } 53 | } 54 | 55 | func GreaterThan(column string, value interface{}) *Condition { 56 | return &Condition{ 57 | Operation: OperatorGreater, 58 | Left: column, 59 | Right: value, 60 | } 61 | } 62 | 63 | func LessThan(column string, value interface{}) *Condition { 64 | return &Condition{ 65 | Operation: OperatorLess, 66 | Left: column, 67 | Right: value, 68 | } 69 | } 70 | 71 | func GreaterOrEqual(column string, value interface{}) *Condition { 72 | return &Condition{ 73 | Operation: OperatorGreaterOrEqual, 74 | Left: column, 75 | Right: value, 76 | } 77 | } 78 | 79 | func LessOrEqual(column string, value interface{}) *Condition { 80 | return &Condition{ 81 | Operation: OperatorLessOrEqual, 82 | Left: column, 83 | Right: value, 84 | } 85 | } 86 | 87 | func In(column string, values []interface{}) *Condition { 88 | return &Condition{ 89 | Operation: OperatorIn, 90 | Left: column, 91 | Right: values, 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /di/di.go: -------------------------------------------------------------------------------- 1 | package di 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | type Dependency interface { 8 | Open() error 9 | Close() 10 | } 11 | 12 | // Container contains dependencies by name. 13 | type Container struct { 14 | dependencies map[string]interface{} 15 | } 16 | 17 | // New creates new Container instance. 18 | func New() *Container { 19 | return &Container{ 20 | dependencies: make(map[string]interface{}), 21 | } 22 | } 23 | 24 | // Provide registers a dependency. 25 | func (c *Container) Provide(name string, dependency interface{}) { 26 | c.dependencies[name] = dependency 27 | } 28 | 29 | // GetByName returns a dependency by name. 30 | func (c *Container) GetByName(name string) interface{} { 31 | return c.dependencies[name] 32 | } 33 | 34 | // GetByType returns a dependency by type. 35 | func (c *Container) GetByType(typ interface{}) interface{} { 36 | t := reflect.TypeOf(typ) 37 | for _, d := range c.dependencies { 38 | dt := reflect.TypeOf(d) 39 | if t.AssignableTo(dt) { 40 | return d 41 | } 42 | } 43 | return nil 44 | } 45 | 46 | // Resolve decorates objects with dependencies and initializes them. 47 | func (c *Container) Resolve() error { 48 | for _, d := range c.dependencies { 49 | c.inject(d) 50 | } 51 | var opened []Dependency 52 | for _, d := range c.dependencies { 53 | if dep, ok := d.(Dependency); ok { 54 | err := dep.Open() 55 | if err != nil { 56 | for _, od := range opened { 57 | od.Close() 58 | } 59 | return err 60 | } 61 | opened = append(opened, dep) 62 | } 63 | } 64 | return nil 65 | } 66 | 67 | // Close closes all dependencies. 68 | func (c *Container) Close() { 69 | for _, d := range c.dependencies { 70 | if dep, ok := d.(Dependency); ok { 71 | dep.Close() 72 | } 73 | } 74 | } 75 | 76 | func (c *Container) inject(obj interface{}) { 77 | t := reflect.TypeOf(obj).Elem() 78 | for i := 0; i < t.NumField(); i++ { 79 | field := t.Field(i) 80 | inject := field.Tag.Get("inject") 81 | if inject != "" { 82 | dependency := c.GetByName(inject) 83 | if dependency != nil { 84 | reflect.ValueOf(obj).Elem().Field(i).Set(reflect.ValueOf(dependency)) 85 | } 86 | } 87 | 88 | for _, d := range c.dependencies { 89 | dt := reflect.TypeOf(d) 90 | if field.Type.AssignableTo(dt) { 91 | reflect.ValueOf(obj).Elem().Field(i).Set(reflect.ValueOf(d)) 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /security/scrypt.go: -------------------------------------------------------------------------------- 1 | package security 2 | 3 | import ( 4 | "bytes" 5 | "crypto/rand" 6 | "encoding/base64" 7 | "encoding/binary" 8 | 9 | "golang.org/x/crypto/scrypt" 10 | ) 11 | 12 | // Scrypt computes scrypt key using data and cost parameters. 13 | func Scrypt(data []byte, n, r, p, keyLength int) ([]byte, error) { 14 | salt := make([]byte, 8) 15 | _, err := rand.Read(salt) 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | hash, err := scrypt.Key(data, salt, n, r, p, keyLength) 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | head := make([]byte, binary.MaxVarintLen64*4) 26 | s := binary.PutUvarint(head, uint64(n)) 27 | s += binary.PutUvarint(head[s:], uint64(r)) 28 | s += binary.PutUvarint(head[s:], uint64(p)) 29 | s += binary.PutUvarint(head[s:], uint64(keyLength)) 30 | hash = append(head[0:s], hash...) 31 | hash = append(salt, hash...) 32 | 33 | return hash, nil 34 | } 35 | 36 | // ScryptToBase64 computes scrypt key and returns the Base64 encoded result. 37 | func ScryptToBase64(data []byte, n, r, p, keyLength int) (string, error) { 38 | hash, err := Scrypt(data, n, r, p, keyLength) 39 | if err != nil { 40 | return "", err 41 | } 42 | return base64.URLEncoding.EncodeToString(hash), nil 43 | } 44 | 45 | // ScryptEquals compares data with scrypt hash and returns true if they are equal. 46 | func ScryptEquals(data, hash []byte) bool { 47 | buf := bytes.NewReader(hash) 48 | salt := make([]byte, 8) 49 | _, err := buf.Read(salt) 50 | if err != nil { 51 | return false 52 | } 53 | n, err := binary.ReadUvarint(buf) 54 | if err != nil { 55 | return false 56 | } 57 | r, err := binary.ReadUvarint(buf) 58 | if err != nil { 59 | return false 60 | } 61 | p, err := binary.ReadUvarint(buf) 62 | if err != nil { 63 | return false 64 | } 65 | keyLength, err := binary.ReadUvarint(buf) 66 | if err != nil { 67 | return false 68 | } 69 | hash = hash[len(hash)-buf.Len():] 70 | 71 | dataHash, err := scrypt.Key(data, salt, int(n), int(r), int(p), int(keyLength)) 72 | if err != nil { 73 | return false 74 | } 75 | 76 | diff := len(hash) ^ len(dataHash) 77 | for i := 0; i < len(hash) && i < len(dataHash); i++ { 78 | diff |= int(hash[i]) ^ int(dataHash[i]) 79 | } 80 | return diff == 0 81 | } 82 | 83 | // ScryptEqualsBase64 compares data with scrypt hash encoded as Base64 string 84 | func ScryptEqualsBase64(data []byte, hash string) bool { 85 | hashBytes, err := base64.URLEncoding.DecodeString(hash) 86 | if err != nil { 87 | return false 88 | } 89 | return ScryptEquals(data, hashBytes) 90 | } 91 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/README.md: -------------------------------------------------------------------------------- 1 | # errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge) 2 | 3 | Package errors provides simple error handling primitives. 4 | 5 | `go get github.com/pkg/errors` 6 | 7 | The traditional error handling idiom in Go is roughly akin to 8 | ```go 9 | if err != nil { 10 | return err 11 | } 12 | ``` 13 | which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error. 14 | 15 | ## Adding context to an error 16 | 17 | The errors.Wrap function returns a new error that adds context to the original error. For example 18 | ```go 19 | _, err := ioutil.ReadAll(r) 20 | if err != nil { 21 | return errors.Wrap(err, "read failed") 22 | } 23 | ``` 24 | ## Retrieving the cause of an error 25 | 26 | Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`. 27 | ```go 28 | type causer interface { 29 | Cause() error 30 | } 31 | ``` 32 | `errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example: 33 | ```go 34 | switch err := errors.Cause(err).(type) { 35 | case *MyError: 36 | // handle specifically 37 | default: 38 | // unknown error 39 | } 40 | ``` 41 | 42 | [Read the package documentation for more information](https://godoc.org/github.com/pkg/errors). 43 | 44 | ## Contributing 45 | 46 | We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high. 47 | 48 | Before proposing a change, please discuss your change by raising an issue. 49 | 50 | ## License 51 | 52 | BSD-2-Clause 53 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC 7 | 2898 / PKCS #5 v2.0. 8 | 9 | A key derivation function is useful when encrypting data based on a password 10 | or any other not-fully-random data. It uses a pseudorandom function to derive 11 | a secure encryption key based on the password. 12 | 13 | While v2.0 of the standard defines only one pseudorandom function to use, 14 | HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved 15 | Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To 16 | choose, you can pass the `New` functions from the different SHA packages to 17 | pbkdf2.Key. 18 | */ 19 | package pbkdf2 // import "golang.org/x/crypto/pbkdf2" 20 | 21 | import ( 22 | "crypto/hmac" 23 | "hash" 24 | ) 25 | 26 | // Key derives a key from the password, salt and iteration count, returning a 27 | // []byte of length keylen that can be used as cryptographic key. The key is 28 | // derived based on the method described as PBKDF2 with the HMAC variant using 29 | // the supplied hash function. 30 | // 31 | // For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you 32 | // can get a derived key for e.g. AES-256 (which needs a 32-byte key) by 33 | // doing: 34 | // 35 | // dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New) 36 | // 37 | // Remember to get a good random salt. At least 8 bytes is recommended by the 38 | // RFC. 39 | // 40 | // Using a higher iteration count will increase the cost of an exhaustive 41 | // search but will also make derivation proportionally slower. 42 | func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { 43 | prf := hmac.New(h, password) 44 | hashLen := prf.Size() 45 | numBlocks := (keyLen + hashLen - 1) / hashLen 46 | 47 | var buf [4]byte 48 | dk := make([]byte, 0, numBlocks*hashLen) 49 | U := make([]byte, hashLen) 50 | for block := 1; block <= numBlocks; block++ { 51 | // N.B.: || means concatenation, ^ means XOR 52 | // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter 53 | // U_1 = PRF(password, salt || uint(i)) 54 | prf.Reset() 55 | prf.Write(salt) 56 | buf[0] = byte(block >> 24) 57 | buf[1] = byte(block >> 16) 58 | buf[2] = byte(block >> 8) 59 | buf[3] = byte(block) 60 | prf.Write(buf[:4]) 61 | dk = prf.Sum(dk) 62 | T := dk[len(dk)-hashLen:] 63 | copy(U, T) 64 | 65 | // U_n = PRF(password, U_(n-1)) 66 | for n := 2; n <= iter; n++ { 67 | prf.Reset() 68 | prf.Write(U) 69 | U = U[:0] 70 | U = prf.Sum(U) 71 | for x := range U { 72 | T[x] ^= U[x] 73 | } 74 | } 75 | } 76 | return dk[:keyLen] 77 | } 78 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/type_check.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | // tomlType represents any Go type that corresponds to a TOML type. 4 | // While the first draft of the TOML spec has a simplistic type system that 5 | // probably doesn't need this level of sophistication, we seem to be militating 6 | // toward adding real composite types. 7 | type tomlType interface { 8 | typeString() string 9 | } 10 | 11 | // typeEqual accepts any two types and returns true if they are equal. 12 | func typeEqual(t1, t2 tomlType) bool { 13 | if t1 == nil || t2 == nil { 14 | return false 15 | } 16 | return t1.typeString() == t2.typeString() 17 | } 18 | 19 | func typeIsHash(t tomlType) bool { 20 | return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash) 21 | } 22 | 23 | type tomlBaseType string 24 | 25 | func (btype tomlBaseType) typeString() string { 26 | return string(btype) 27 | } 28 | 29 | func (btype tomlBaseType) String() string { 30 | return btype.typeString() 31 | } 32 | 33 | var ( 34 | tomlInteger tomlBaseType = "Integer" 35 | tomlFloat tomlBaseType = "Float" 36 | tomlDatetime tomlBaseType = "Datetime" 37 | tomlString tomlBaseType = "String" 38 | tomlBool tomlBaseType = "Bool" 39 | tomlArray tomlBaseType = "Array" 40 | tomlHash tomlBaseType = "Hash" 41 | tomlArrayHash tomlBaseType = "ArrayHash" 42 | ) 43 | 44 | // typeOfPrimitive returns a tomlType of any primitive value in TOML. 45 | // Primitive values are: Integer, Float, Datetime, String and Bool. 46 | // 47 | // Passing a lexer item other than the following will cause a BUG message 48 | // to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime. 49 | func (p *parser) typeOfPrimitive(lexItem item) tomlType { 50 | switch lexItem.typ { 51 | case itemInteger: 52 | return tomlInteger 53 | case itemFloat: 54 | return tomlFloat 55 | case itemDatetime: 56 | return tomlDatetime 57 | case itemString: 58 | return tomlString 59 | case itemMultilineString: 60 | return tomlString 61 | case itemRawString: 62 | return tomlString 63 | case itemRawMultilineString: 64 | return tomlString 65 | case itemBool: 66 | return tomlBool 67 | } 68 | p.bug("Cannot infer primitive type of lex item '%s'.", lexItem) 69 | panic("unreachable") 70 | } 71 | 72 | // typeOfArray returns a tomlType for an array given a list of types of its 73 | // values. 74 | // 75 | // In the current spec, if an array is homogeneous, then its type is always 76 | // "Array". If the array is not homogeneous, an error is generated. 77 | func (p *parser) typeOfArray(types []tomlType) tomlType { 78 | // Empty arrays are cool. 79 | if len(types) == 0 { 80 | return tomlArray 81 | } 82 | 83 | theType := types[0] 84 | for _, t := range types[1:] { 85 | if !typeEqual(theType, t) { 86 | p.panicf("Array contains values of type '%s' and '%s', but "+ 87 | "arrays must be homogeneous.", theType, t) 88 | } 89 | } 90 | return tomlArray 91 | } 92 | -------------------------------------------------------------------------------- /valid/text_test.go: -------------------------------------------------------------------------------- 1 | package valid 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestTextRegexp(t *testing.T) { 10 | v := New( 11 | Regexp("^[a-z]+$"), 12 | ) 13 | assert.NoError(t, v.Validate("abc")) 14 | assert.Equal(t, ErrInvalidTextPattern, v.Validate("Aabc")) 15 | } 16 | 17 | func TestTextMaxLength(t *testing.T) { 18 | v := New( 19 | MaxLength(4), 20 | ) 21 | assert.NoError(t, v.Validate("abc")) 22 | assert.Equal(t, ErrTextTooLong, v.Validate("abcde")) 23 | } 24 | 25 | func TestTextMinLength(t *testing.T) { 26 | v := New( 27 | MinLength(4), 28 | ) 29 | assert.NoError(t, v.Validate("abcde")) 30 | assert.Error(t, ErrTextTooShort, v.Validate("abc")) 31 | } 32 | 33 | func TestTextMinMaxLength(t *testing.T) { 34 | v := New( 35 | MinMaxLength(3, 5), 36 | ) 37 | assert.NoError(t, v.Validate("123")) 38 | assert.NoError(t, v.Validate("1234")) 39 | assert.NoError(t, v.Validate("12345")) 40 | assert.Equal(t, ErrTextTooShort, v.Validate("12")) 41 | assert.Equal(t, ErrTextTooLong, v.Validate("123456")) 42 | } 43 | 44 | func TestTextHasUpperCase(t *testing.T) { 45 | v := New( 46 | HasUpperCase(), 47 | ) 48 | 49 | assert.NoError(t, v.Validate("Abc")) 50 | assert.Equal(t, ErrTextMissingUpper, v.Validate("")) 51 | assert.Equal(t, ErrTextMissingUpper, v.Validate("abc")) 52 | } 53 | 54 | func TestTextHasLowerCase(t *testing.T) { 55 | v := New( 56 | HasLowerCase(), 57 | ) 58 | 59 | assert.NoError(t, v.Validate("ABc")) 60 | assert.Equal(t, ErrTextMissingLower, v.Validate("")) 61 | assert.Equal(t, ErrTextMissingLower, v.Validate("ABC")) 62 | } 63 | 64 | func TestTextHasSpecial(t *testing.T) { 65 | v := New( 66 | HasSpecial(), 67 | ) 68 | 69 | assert.NoError(t, v.Validate("abc!")) 70 | assert.Equal(t, ErrTextMissingSpecial, v.Validate("")) 71 | assert.Equal(t, ErrTextMissingSpecial, v.Validate("abc4")) 72 | } 73 | 74 | func TestTextHasNumber(t *testing.T) { 75 | v := New( 76 | HasNumber(), 77 | ) 78 | 79 | assert.NoError(t, v.Validate("abc42")) 80 | assert.Equal(t, ErrTextMissingNumber, v.Validate("")) 81 | assert.Equal(t, ErrTextMissingNumber, v.Validate("abc_")) 82 | } 83 | 84 | func TestTextEmail(t *testing.T) { 85 | v := New( 86 | Email(), 87 | ) 88 | 89 | assert.NoError(t, v.Validate("user@example.com")) 90 | assert.Equal(t, ErrInvalidEmail, v.Validate("a")) 91 | assert.Equal(t, ErrInvalidEmail, v.Validate("example1234@")) 92 | assert.Equal(t, ErrInvalidEmail, v.Validate("@example1234.com")) 93 | assert.Equal(t, ErrInvalidEmail, v.Validate("user@example")) 94 | } 95 | 96 | func TestTextSlug(t *testing.T) { 97 | v := New( 98 | Slug(), 99 | ) 100 | 101 | assert.NoError(t, v.Validate("hello-world")) 102 | 103 | invalidSlugs := []string{ 104 | "", 105 | "a-", 106 | "-a", 107 | "a-$-a", 108 | "-", 109 | "a---", 110 | "A", 111 | } 112 | for _, slug := range invalidSlugs { 113 | assert.Equal(t, ErrTextInvalidSlug, v.Validate(slug)) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/sorter.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "reflect" 5 | "unicode" 6 | ) 7 | 8 | type keyList []reflect.Value 9 | 10 | func (l keyList) Len() int { return len(l) } 11 | func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } 12 | func (l keyList) Less(i, j int) bool { 13 | a := l[i] 14 | b := l[j] 15 | ak := a.Kind() 16 | bk := b.Kind() 17 | for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { 18 | a = a.Elem() 19 | ak = a.Kind() 20 | } 21 | for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { 22 | b = b.Elem() 23 | bk = b.Kind() 24 | } 25 | af, aok := keyFloat(a) 26 | bf, bok := keyFloat(b) 27 | if aok && bok { 28 | if af != bf { 29 | return af < bf 30 | } 31 | if ak != bk { 32 | return ak < bk 33 | } 34 | return numLess(a, b) 35 | } 36 | if ak != reflect.String || bk != reflect.String { 37 | return ak < bk 38 | } 39 | ar, br := []rune(a.String()), []rune(b.String()) 40 | for i := 0; i < len(ar) && i < len(br); i++ { 41 | if ar[i] == br[i] { 42 | continue 43 | } 44 | al := unicode.IsLetter(ar[i]) 45 | bl := unicode.IsLetter(br[i]) 46 | if al && bl { 47 | return ar[i] < br[i] 48 | } 49 | if al || bl { 50 | return bl 51 | } 52 | var ai, bi int 53 | var an, bn int64 54 | if ar[i] == '0' || br[i] == '0' { 55 | for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- { 56 | if ar[j] != '0' { 57 | an = 1 58 | bn = 1 59 | break 60 | } 61 | } 62 | } 63 | for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { 64 | an = an*10 + int64(ar[ai]-'0') 65 | } 66 | for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { 67 | bn = bn*10 + int64(br[bi]-'0') 68 | } 69 | if an != bn { 70 | return an < bn 71 | } 72 | if ai != bi { 73 | return ai < bi 74 | } 75 | return ar[i] < br[i] 76 | } 77 | return len(ar) < len(br) 78 | } 79 | 80 | // keyFloat returns a float value for v if it is a number/bool 81 | // and whether it is a number/bool or not. 82 | func keyFloat(v reflect.Value) (f float64, ok bool) { 83 | switch v.Kind() { 84 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 85 | return float64(v.Int()), true 86 | case reflect.Float32, reflect.Float64: 87 | return v.Float(), true 88 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 89 | return float64(v.Uint()), true 90 | case reflect.Bool: 91 | if v.Bool() { 92 | return 1, true 93 | } 94 | return 0, true 95 | } 96 | return 0, false 97 | } 98 | 99 | // numLess returns whether a < b. 100 | // a and b must necessarily have the same kind. 101 | func numLess(a, b reflect.Value) bool { 102 | switch a.Kind() { 103 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 104 | return a.Int() < b.Int() 105 | case reflect.Float32, reflect.Float64: 106 | return a.Float() < b.Float() 107 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 108 | return a.Uint() < b.Uint() 109 | case reflect.Bool: 110 | return !a.Bool() && b.Bool() 111 | } 112 | panic("not a number") 113 | } 114 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/mergo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Dario Castañé. All rights reserved. 2 | // Copyright 2009 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // Based on src/pkg/reflect/deepequal.go from official 7 | // golang's stdlib. 8 | 9 | package mergo 10 | 11 | import ( 12 | "errors" 13 | "reflect" 14 | ) 15 | 16 | // Errors reported by Mergo when it finds invalid arguments. 17 | var ( 18 | ErrNilArguments = errors.New("src and dst must not be nil") 19 | ErrDifferentArgumentsTypes = errors.New("src and dst must be of same type") 20 | ErrNotSupported = errors.New("only structs and maps are supported") 21 | ErrExpectedMapAsDestination = errors.New("dst was expected to be a map") 22 | ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct") 23 | ) 24 | 25 | // During deepMerge, must keep track of checks that are 26 | // in progress. The comparison algorithm assumes that all 27 | // checks in progress are true when it reencounters them. 28 | // Visited are stored in a map indexed by 17 * a1 + a2; 29 | type visit struct { 30 | ptr uintptr 31 | typ reflect.Type 32 | next *visit 33 | } 34 | 35 | // From src/pkg/encoding/json/encode.go. 36 | func isEmptyValue(v reflect.Value) bool { 37 | switch v.Kind() { 38 | case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 39 | return v.Len() == 0 40 | case reflect.Bool: 41 | return !v.Bool() 42 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 43 | return v.Int() == 0 44 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 45 | return v.Uint() == 0 46 | case reflect.Float32, reflect.Float64: 47 | return v.Float() == 0 48 | case reflect.Interface, reflect.Ptr: 49 | if v.IsNil() { 50 | return true 51 | } 52 | return isEmptyValue(v.Elem()) 53 | case reflect.Func: 54 | return v.IsNil() 55 | case reflect.Invalid: 56 | return true 57 | } 58 | return false 59 | } 60 | 61 | func resolveValues(dst, src interface{}) (vDst, vSrc reflect.Value, err error) { 62 | if dst == nil || src == nil { 63 | err = ErrNilArguments 64 | return 65 | } 66 | vDst = reflect.ValueOf(dst).Elem() 67 | if vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map { 68 | err = ErrNotSupported 69 | return 70 | } 71 | vSrc = reflect.ValueOf(src) 72 | // We check if vSrc is a pointer to dereference it. 73 | if vSrc.Kind() == reflect.Ptr { 74 | vSrc = vSrc.Elem() 75 | } 76 | return 77 | } 78 | 79 | // Traverses recursively both values, assigning src's fields values to dst. 80 | // The map argument tracks comparisons that have already been seen, which allows 81 | // short circuiting on recursive types. 82 | func deeper(dst, src reflect.Value, visited map[uintptr]*visit, depth int) (err error) { 83 | if dst.CanAddr() { 84 | addr := dst.UnsafeAddr() 85 | h := 17 * addr 86 | seen := visited[h] 87 | typ := dst.Type() 88 | for p := seen; p != nil; p = p.next { 89 | if p.ptr == addr && p.typ == typ { 90 | return nil 91 | } 92 | } 93 | // Remember, remember... 94 | visited[h] = &visit{addr, typ, seen} 95 | } 96 | return // TODO refactor 97 | } 98 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at i@dario.im. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/README.md: -------------------------------------------------------------------------------- 1 | # YAML support for the Go language 2 | 3 | Introduction 4 | ------------ 5 | 6 | The yaml package enables Go programs to comfortably encode and decode YAML 7 | values. It was developed within [Canonical](https://www.canonical.com) as 8 | part of the [juju](https://juju.ubuntu.com) project, and is based on a 9 | pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) 10 | C library to parse and generate YAML data quickly and reliably. 11 | 12 | Compatibility 13 | ------------- 14 | 15 | The yaml package supports most of YAML 1.1 and 1.2, including support for 16 | anchors, tags, map merging, etc. Multi-document unmarshalling is not yet 17 | implemented, and base-60 floats from YAML 1.1 are purposefully not 18 | supported since they're a poor design and are gone in YAML 1.2. 19 | 20 | Installation and usage 21 | ---------------------- 22 | 23 | The import path for the package is *gopkg.in/yaml.v2*. 24 | 25 | To install it, run: 26 | 27 | go get gopkg.in/yaml.v2 28 | 29 | API documentation 30 | ----------------- 31 | 32 | If opened in a browser, the import path itself leads to the API documentation: 33 | 34 | * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) 35 | 36 | API stability 37 | ------------- 38 | 39 | The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). 40 | 41 | 42 | License 43 | ------- 44 | 45 | The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. 46 | 47 | 48 | Example 49 | ------- 50 | 51 | ```Go 52 | package main 53 | 54 | import ( 55 | "fmt" 56 | "log" 57 | 58 | "gopkg.in/yaml.v2" 59 | ) 60 | 61 | var data = ` 62 | a: Easy! 63 | b: 64 | c: 2 65 | d: [3, 4] 66 | ` 67 | 68 | // Note: struct fields must be public in order for unmarshal to 69 | // correctly populate the data. 70 | type T struct { 71 | A string 72 | B struct { 73 | RenamedC int `yaml:"c"` 74 | D []int `yaml:",flow"` 75 | } 76 | } 77 | 78 | func main() { 79 | t := T{} 80 | 81 | err := yaml.Unmarshal([]byte(data), &t) 82 | if err != nil { 83 | log.Fatalf("error: %v", err) 84 | } 85 | fmt.Printf("--- t:\n%v\n\n", t) 86 | 87 | d, err := yaml.Marshal(&t) 88 | if err != nil { 89 | log.Fatalf("error: %v", err) 90 | } 91 | fmt.Printf("--- t dump:\n%s\n\n", string(d)) 92 | 93 | m := make(map[interface{}]interface{}) 94 | 95 | err = yaml.Unmarshal([]byte(data), &m) 96 | if err != nil { 97 | log.Fatalf("error: %v", err) 98 | } 99 | fmt.Printf("--- m:\n%v\n\n", m) 100 | 101 | d, err = yaml.Marshal(&m) 102 | if err != nil { 103 | log.Fatalf("error: %v", err) 104 | } 105 | fmt.Printf("--- m dump:\n%s\n\n", string(d)) 106 | } 107 | ``` 108 | 109 | This example will generate the following output: 110 | 111 | ``` 112 | --- t: 113 | {Easy! {2 [3 4]}} 114 | 115 | --- t dump: 116 | a: Easy! 117 | b: 118 | c: 2 119 | d: [3, 4] 120 | 121 | 122 | --- m: 123 | map[a:Easy! b:map[c:2 d:[3 4]]] 124 | 125 | --- m dump: 126 | a: Easy! 127 | b: 128 | c: 2 129 | d: 130 | - 3 131 | - 4 132 | ``` 133 | 134 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/decode_meta.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | import "strings" 4 | 5 | // MetaData allows access to meta information about TOML data that may not 6 | // be inferrable via reflection. In particular, whether a key has been defined 7 | // and the TOML type of a key. 8 | type MetaData struct { 9 | mapping map[string]interface{} 10 | types map[string]tomlType 11 | keys []Key 12 | decoded map[string]bool 13 | context Key // Used only during decoding. 14 | } 15 | 16 | // IsDefined returns true if the key given exists in the TOML data. The key 17 | // should be specified hierarchially. e.g., 18 | // 19 | // // access the TOML key 'a.b.c' 20 | // IsDefined("a", "b", "c") 21 | // 22 | // IsDefined will return false if an empty key given. Keys are case sensitive. 23 | func (md *MetaData) IsDefined(key ...string) bool { 24 | if len(key) == 0 { 25 | return false 26 | } 27 | 28 | var hash map[string]interface{} 29 | var ok bool 30 | var hashOrVal interface{} = md.mapping 31 | for _, k := range key { 32 | if hash, ok = hashOrVal.(map[string]interface{}); !ok { 33 | return false 34 | } 35 | if hashOrVal, ok = hash[k]; !ok { 36 | return false 37 | } 38 | } 39 | return true 40 | } 41 | 42 | // Type returns a string representation of the type of the key specified. 43 | // 44 | // Type will return the empty string if given an empty key or a key that 45 | // does not exist. Keys are case sensitive. 46 | func (md *MetaData) Type(key ...string) string { 47 | fullkey := strings.Join(key, ".") 48 | if typ, ok := md.types[fullkey]; ok { 49 | return typ.typeString() 50 | } 51 | return "" 52 | } 53 | 54 | // Key is the type of any TOML key, including key groups. Use (MetaData).Keys 55 | // to get values of this type. 56 | type Key []string 57 | 58 | func (k Key) String() string { 59 | return strings.Join(k, ".") 60 | } 61 | 62 | func (k Key) maybeQuotedAll() string { 63 | var ss []string 64 | for i := range k { 65 | ss = append(ss, k.maybeQuoted(i)) 66 | } 67 | return strings.Join(ss, ".") 68 | } 69 | 70 | func (k Key) maybeQuoted(i int) string { 71 | quote := false 72 | for _, c := range k[i] { 73 | if !isBareKeyChar(c) { 74 | quote = true 75 | break 76 | } 77 | } 78 | if quote { 79 | return "\"" + strings.Replace(k[i], "\"", "\\\"", -1) + "\"" 80 | } 81 | return k[i] 82 | } 83 | 84 | func (k Key) add(piece string) Key { 85 | newKey := make(Key, len(k)+1) 86 | copy(newKey, k) 87 | newKey[len(k)] = piece 88 | return newKey 89 | } 90 | 91 | // Keys returns a slice of every key in the TOML data, including key groups. 92 | // Each key is itself a slice, where the first element is the top of the 93 | // hierarchy and the last is the most specific. 94 | // 95 | // The list will have the same order as the keys appeared in the TOML data. 96 | // 97 | // All keys returned are non-empty. 98 | func (md *MetaData) Keys() []Key { 99 | return md.keys 100 | } 101 | 102 | // Undecoded returns all keys that have not been decoded in the order in which 103 | // they appear in the original TOML document. 104 | // 105 | // This includes keys that haven't been decoded because of a Primitive value. 106 | // Once the Primitive value is decoded, the keys will be considered decoded. 107 | // 108 | // Also note that decoding into an empty interface will result in no decoding, 109 | // and so no keys will be considered decoded. 110 | // 111 | // In this sense, the Undecoded keys correspond to keys in the TOML document 112 | // that do not have a concrete type in your representation. 113 | func (md *MetaData) Undecoded() []Key { 114 | undecoded := make([]Key, 0, len(md.keys)) 115 | for _, key := range md.keys { 116 | if !md.decoded[key.String()] { 117 | undecoded = append(undecoded, key) 118 | } 119 | } 120 | return undecoded 121 | } 122 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/stack.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "path" 7 | "runtime" 8 | "strings" 9 | ) 10 | 11 | // Frame represents a program counter inside a stack frame. 12 | type Frame uintptr 13 | 14 | // pc returns the program counter for this frame; 15 | // multiple frames may have the same PC value. 16 | func (f Frame) pc() uintptr { return uintptr(f) - 1 } 17 | 18 | // file returns the full path to the file that contains the 19 | // function for this Frame's pc. 20 | func (f Frame) file() string { 21 | fn := runtime.FuncForPC(f.pc()) 22 | if fn == nil { 23 | return "unknown" 24 | } 25 | file, _ := fn.FileLine(f.pc()) 26 | return file 27 | } 28 | 29 | // line returns the line number of source code of the 30 | // function for this Frame's pc. 31 | func (f Frame) line() int { 32 | fn := runtime.FuncForPC(f.pc()) 33 | if fn == nil { 34 | return 0 35 | } 36 | _, line := fn.FileLine(f.pc()) 37 | return line 38 | } 39 | 40 | // Format formats the frame according to the fmt.Formatter interface. 41 | // 42 | // %s source file 43 | // %d source line 44 | // %n function name 45 | // %v equivalent to %s:%d 46 | // 47 | // Format accepts flags that alter the printing of some verbs, as follows: 48 | // 49 | // %+s function name and path of source file relative to the compile time 50 | // GOPATH separated by \n\t (\n\t) 51 | // %+v equivalent to %+s:%d 52 | func (f Frame) Format(s fmt.State, verb rune) { 53 | switch verb { 54 | case 's': 55 | switch { 56 | case s.Flag('+'): 57 | pc := f.pc() 58 | fn := runtime.FuncForPC(pc) 59 | if fn == nil { 60 | io.WriteString(s, "unknown") 61 | } else { 62 | file, _ := fn.FileLine(pc) 63 | fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file) 64 | } 65 | default: 66 | io.WriteString(s, path.Base(f.file())) 67 | } 68 | case 'd': 69 | fmt.Fprintf(s, "%d", f.line()) 70 | case 'n': 71 | name := runtime.FuncForPC(f.pc()).Name() 72 | io.WriteString(s, funcname(name)) 73 | case 'v': 74 | f.Format(s, 's') 75 | io.WriteString(s, ":") 76 | f.Format(s, 'd') 77 | } 78 | } 79 | 80 | // StackTrace is stack of Frames from innermost (newest) to outermost (oldest). 81 | type StackTrace []Frame 82 | 83 | // Format formats the stack of Frames according to the fmt.Formatter interface. 84 | // 85 | // %s lists source files for each Frame in the stack 86 | // %v lists the source file and line number for each Frame in the stack 87 | // 88 | // Format accepts flags that alter the printing of some verbs, as follows: 89 | // 90 | // %+v Prints filename, function, and line number for each Frame in the stack. 91 | func (st StackTrace) Format(s fmt.State, verb rune) { 92 | switch verb { 93 | case 'v': 94 | switch { 95 | case s.Flag('+'): 96 | for _, f := range st { 97 | fmt.Fprintf(s, "\n%+v", f) 98 | } 99 | case s.Flag('#'): 100 | fmt.Fprintf(s, "%#v", []Frame(st)) 101 | default: 102 | fmt.Fprintf(s, "%v", []Frame(st)) 103 | } 104 | case 's': 105 | fmt.Fprintf(s, "%s", []Frame(st)) 106 | } 107 | } 108 | 109 | // stack represents a stack of program counters. 110 | type stack []uintptr 111 | 112 | func (s *stack) Format(st fmt.State, verb rune) { 113 | switch verb { 114 | case 'v': 115 | switch { 116 | case st.Flag('+'): 117 | for _, pc := range *s { 118 | f := Frame(pc) 119 | fmt.Fprintf(st, "\n%+v", f) 120 | } 121 | } 122 | } 123 | } 124 | 125 | func (s *stack) StackTrace() StackTrace { 126 | f := make([]Frame, len(*s)) 127 | for i := 0; i < len(f); i++ { 128 | f[i] = Frame((*s)[i]) 129 | } 130 | return f 131 | } 132 | 133 | func callers() *stack { 134 | const depth = 32 135 | var pcs [depth]uintptr 136 | n := runtime.Callers(3, pcs[:]) 137 | var st stack = pcs[0:n] 138 | return &st 139 | } 140 | 141 | // funcname removes the path prefix component of a function's name reported by func.Name(). 142 | func funcname(name string) string { 143 | i := strings.LastIndex(name, "/") 144 | name = name[i+1:] 145 | i = strings.Index(name, ".") 146 | return name[i+1:] 147 | } 148 | -------------------------------------------------------------------------------- /query/cassandra_dialect.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type cassandraDialect struct { 9 | } 10 | 11 | func (d *cassandraDialect) BuildQuery(q Query) (string, []interface{}, error) { 12 | b := strings.Builder{} 13 | args := make([]interface{}, 0) 14 | 15 | b.WriteString("SELECT ") 16 | for i, c := range q.columns { 17 | b.WriteString(c) 18 | if i < len(q.columns)-1 { 19 | b.WriteString(", ") 20 | } 21 | } 22 | 23 | b.WriteString(" FROM ") 24 | b.WriteString(q.from) 25 | 26 | b.WriteString(" WHERE ") 27 | for i, c := range q.conditions { 28 | cs, ca, err := d.buildCondition(c) 29 | if err != nil { 30 | return "", nil, err 31 | } 32 | b.WriteString(cs) 33 | args = append(args, ca...) 34 | 35 | if i < len(q.conditions)-1 { 36 | b.WriteString(" AND ") 37 | } 38 | } 39 | 40 | if q.take != -1 { 41 | b.WriteString(" LIMIT ") 42 | b.WriteString(fmt.Sprint(q.take)) 43 | } 44 | 45 | b.WriteString(" ALLOW FILTERING") 46 | 47 | return b.String(), args, nil 48 | } 49 | 50 | func (d *cassandraDialect) BuildInsert(i Insert) (string, []interface{}, error) { 51 | b := strings.Builder{} 52 | args := make([]interface{}, 0) 53 | 54 | b.WriteString("INSERT INTO ") 55 | b.WriteString(i.into) 56 | b.WriteString("(") 57 | for j, c := range i.columns { 58 | b.WriteString(c) 59 | if j < len(i.columns)-1 { 60 | b.WriteString(", ") 61 | } 62 | } 63 | b.WriteString(")") 64 | 65 | b.WriteString(" VALUES ") 66 | 67 | for j, row := range i.rows { 68 | b.WriteString("(") 69 | for k, v := range row { 70 | b.WriteString("?") 71 | args = append(args, v) 72 | if k < len(row)-1 { 73 | b.WriteString(", ") 74 | } 75 | } 76 | b.WriteString(")") 77 | if j < len(i.rows)-1 { 78 | b.WriteString(", ") 79 | } 80 | } 81 | 82 | return b.String(), args, nil 83 | } 84 | 85 | func (d *cassandraDialect) BuildUpdate(u Update) (string, []interface{}, error) { 86 | b := strings.Builder{} 87 | args := make([]interface{}, 0) 88 | 89 | b.WriteString("UPDATE ") 90 | b.WriteString(u.table) 91 | 92 | b.WriteString(" SET ") 93 | for j, a := range u.assignments { 94 | b.WriteString(a.Column) 95 | b.WriteString(" = ?") 96 | if j < len(u.assignments)-1 { 97 | b.WriteString(", ") 98 | } 99 | args = append(args, a.Value) 100 | } 101 | 102 | b.WriteString(" WHERE ") 103 | for i, c := range u.conditions { 104 | cs, ca, err := d.buildCondition(c) 105 | if err != nil { 106 | return "", nil, err 107 | } 108 | b.WriteString(cs) 109 | args = append(args, ca...) 110 | 111 | if i < len(u.conditions)-1 { 112 | b.WriteString(" AND ") 113 | } 114 | } 115 | 116 | return b.String(), args, nil 117 | } 118 | 119 | func (d *cassandraDialect) buildCondition(c *Condition) (string, []interface{}, error) { 120 | stmt := strings.Builder{} 121 | args := make([]interface{}, 0) 122 | 123 | if lc, ok := c.Left.(*Condition); ok { 124 | ls, la, err := d.buildCondition(lc) 125 | if err != nil { 126 | return "", nil, err 127 | } 128 | stmt.WriteString(ls) 129 | args = append(args, la...) 130 | } else if lc, ok := c.Left.(string); ok { 131 | stmt.WriteString(lc) 132 | } else { 133 | return "", nil, ErrInvalidCondition 134 | } 135 | 136 | switch c.Operation { 137 | case OperatorAnd: 138 | stmt.WriteString(" AND ") 139 | case OperatorOr: 140 | stmt.WriteString(" OR ") 141 | case OperatorEqual: 142 | stmt.WriteString(" = ") 143 | case OperatorNotEqual: 144 | stmt.WriteString(" != ") 145 | case OperatorGreater: 146 | stmt.WriteString(" > ") 147 | case OperatorLess: 148 | stmt.WriteString(" < ") 149 | case OperatorGreaterOrEqual: 150 | stmt.WriteString(" >= ") 151 | case OperatorLessOrEqual: 152 | stmt.WriteString(" <= ") 153 | case OperatorIn: 154 | stmt.WriteString(" IN ") 155 | } 156 | 157 | if rc, ok := c.Right.(*Condition); ok { 158 | rs, ra, err := d.buildCondition(rc) 159 | if err != nil { 160 | return "", nil, err 161 | } 162 | stmt.WriteString(rs) 163 | args = append(args, ra...) 164 | } else if values, ok := c.Right.([]interface{}); ok { 165 | stmt.WriteString("(") 166 | for i := 0; i < len(values); i++ { 167 | stmt.WriteString("?") 168 | if i < len(values)-1 { 169 | stmt.WriteString(", ") 170 | } 171 | } 172 | stmt.WriteString(")") 173 | args = append(args, values...) 174 | } else { 175 | stmt.WriteString("?") 176 | args = append(args, c.Right) 177 | } 178 | 179 | return stmt.String(), args, nil 180 | } 181 | -------------------------------------------------------------------------------- /valid/text.go: -------------------------------------------------------------------------------- 1 | package valid 2 | 3 | import ( 4 | "errors" 5 | "regexp" 6 | "strings" 7 | "unicode" 8 | ) 9 | 10 | var ( 11 | emailUserRegexp = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+$") 12 | emailHostRegexp = regexp.MustCompile("^[^\\s]+\\.[^\\s]+$") 13 | slugRegexp = regexp.MustCompile("^[a-z0-9]+(?:-[a-z0-9]+)*$") 14 | ) 15 | 16 | var ( 17 | ErrInvalidTextPattern = errors.New("invalid text pattern") 18 | ErrTextTooLong = errors.New("text is too long") 19 | ErrTextTooShort = errors.New("text is too short") 20 | ErrTextMissingUpper = errors.New("missing uppercase character") 21 | ErrTextMissingLower = errors.New("missing lowercase character") 22 | ErrTextMissingSpecial = errors.New("missing special character") 23 | ErrTextMissingNumber = errors.New("missing number") 24 | 25 | ErrInvalidEmail = errors.New("invalid email") 26 | ErrTextInvalidSlug = errors.New("invalid slug") 27 | ) 28 | 29 | func Regexp(s string) Constraint { 30 | exp := regexp.MustCompile(s) 31 | return func(value interface{}) error { 32 | v, ok := value.(string) 33 | if !ok { 34 | return ErrIncompatibleTypes 35 | } 36 | if !exp.MatchString(v) { 37 | return ErrInvalidTextPattern 38 | } 39 | return nil 40 | } 41 | } 42 | 43 | func MaxLength(n int) Constraint { 44 | return func(value interface{}) error { 45 | v, ok := value.(string) 46 | if !ok { 47 | return ErrIncompatibleTypes 48 | } 49 | 50 | if len(v) > n { 51 | return ErrTextTooLong 52 | } 53 | 54 | return nil 55 | } 56 | } 57 | 58 | func MinLength(n int) Constraint { 59 | return func(value interface{}) error { 60 | v, ok := value.(string) 61 | if !ok { 62 | return ErrIncompatibleTypes 63 | } 64 | 65 | if len(v) < n { 66 | return ErrTextTooShort 67 | } 68 | 69 | return nil 70 | } 71 | } 72 | 73 | func MinMaxLength(min, max int) Constraint { 74 | return func(value interface{}) error { 75 | v, ok := value.(string) 76 | if !ok { 77 | return ErrIncompatibleTypes 78 | } 79 | 80 | if len(v) < min { 81 | return ErrTextTooShort 82 | } 83 | 84 | if len(v) > max { 85 | return ErrTextTooLong 86 | } 87 | 88 | return nil 89 | } 90 | } 91 | 92 | func HasUpperCase() Constraint { 93 | return func(value interface{}) error { 94 | v, ok := value.(string) 95 | if !ok { 96 | return ErrIncompatibleTypes 97 | } 98 | for _, r := range []rune(v) { 99 | if unicode.IsUpper(r) { 100 | return nil 101 | } 102 | } 103 | return ErrTextMissingUpper 104 | } 105 | } 106 | 107 | func HasLowerCase() Constraint { 108 | return func(value interface{}) error { 109 | v, ok := value.(string) 110 | if !ok { 111 | return ErrIncompatibleTypes 112 | } 113 | for _, r := range []rune(v) { 114 | if unicode.IsLower(r) { 115 | return nil 116 | } 117 | } 118 | return ErrTextMissingLower 119 | } 120 | } 121 | 122 | func HasSpecial() Constraint { 123 | return func(value interface{}) error { 124 | v, ok := value.(string) 125 | if !ok { 126 | return ErrIncompatibleTypes 127 | } 128 | for _, r := range []rune(v) { 129 | if unicode.IsPunct(r) || unicode.IsSymbol(r) { 130 | return nil 131 | } 132 | } 133 | return ErrTextMissingSpecial 134 | } 135 | } 136 | 137 | func HasNumber() Constraint { 138 | return func(value interface{}) error { 139 | v, ok := value.(string) 140 | if !ok { 141 | return ErrIncompatibleTypes 142 | } 143 | for _, r := range []rune(v) { 144 | if unicode.IsNumber(r) { 145 | return nil 146 | } 147 | } 148 | return ErrTextMissingNumber 149 | } 150 | } 151 | 152 | func Email() Constraint { 153 | return func(value interface{}) error { 154 | v, ok := value.(string) 155 | if !ok { 156 | return ErrIncompatibleTypes 157 | } 158 | 159 | if len(v) < 6 || len(v) > 254 { 160 | return ErrInvalidEmail 161 | } 162 | 163 | at := strings.LastIndex(v, "@") 164 | if at <= 0 || at > len(v)-3 { 165 | return ErrInvalidEmail 166 | } 167 | 168 | user := v[:at] 169 | host := v[at+1:] 170 | 171 | if len(user) > 64 { 172 | return ErrInvalidEmail 173 | } 174 | 175 | if !emailUserRegexp.MatchString(user) || !emailHostRegexp.MatchString(host) { 176 | return ErrInvalidEmail 177 | } 178 | 179 | return nil 180 | } 181 | } 182 | 183 | func Slug() Constraint { 184 | return func(value interface{}) error { 185 | v, ok := value.(string) 186 | if !ok { 187 | return ErrIncompatibleTypes 188 | } 189 | 190 | if !slugRegexp.MatchString(v) { 191 | return ErrTextInvalidSlug 192 | } 193 | 194 | return nil 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /expr/eval.go: -------------------------------------------------------------------------------- 1 | package expr 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | "go/ast" 6 | "go/token" 7 | "math" 8 | "strconv" 9 | ) 10 | 11 | type EvaluatorFunc func(s *Stack) interface{} 12 | 13 | type evaluator struct { 14 | identifiers map[string]interface{} 15 | stack *Stack 16 | err error 17 | } 18 | 19 | func newEvaluator() *evaluator { 20 | e := &evaluator{ 21 | identifiers: make(map[string]interface{}), 22 | stack: NewStack(), 23 | } 24 | e.useCoreLibrary() 25 | return e 26 | } 27 | 28 | func (e *evaluator) Evaluate(node ast.Node) (interface{}, error) { 29 | ast.Walk(e, node) 30 | if e.err != nil { 31 | return nil, e.err 32 | } 33 | if !e.stack.IsEmpty() { 34 | return e.stack.Tail(), nil 35 | } 36 | return nil, errors.New("empty expression") 37 | } 38 | 39 | func (e *evaluator) Visit(node ast.Node) ast.Visitor { 40 | switch n := node.(type) { 41 | case *ast.BasicLit: 42 | e.VisitBasicLiteral(n) 43 | case *ast.Ident: 44 | e.VisitIdentifier(n) 45 | case *ast.BinaryExpr: 46 | e.VisitBinaryExpression(n) 47 | case *ast.UnaryExpr: 48 | e.VisitUnaryExpression(n) 49 | case *ast.ParenExpr: 50 | e.VisitParenthesesExpression(n) 51 | case *ast.CallExpr: 52 | e.VisitCallExpression(n) 53 | default: 54 | } 55 | return nil 56 | } 57 | 58 | func (e *evaluator) VisitBasicLiteral(n *ast.BasicLit) { 59 | var x interface{} 60 | switch n.Kind { 61 | case token.INT, token.FLOAT: 62 | x, _ = strconv.ParseFloat(n.Value, 64) 63 | case token.STRING: 64 | x = n.Value 65 | } 66 | e.stack.Push(x) 67 | } 68 | 69 | func (e *evaluator) VisitBinaryExpression(n *ast.BinaryExpr) { 70 | ast.Walk(e, n.X) 71 | ast.Walk(e, n.Y) 72 | 73 | y := e.stack.Pop() 74 | x := e.stack.Pop() 75 | 76 | switch x := x.(type) { 77 | case float64: 78 | switch y := y.(type) { 79 | case float64: 80 | switch n.Op { 81 | case token.ADD: 82 | e.stack.Push(x + y) 83 | case token.SUB: 84 | e.stack.Push(x - y) 85 | case token.MUL: 86 | e.stack.Push(x * y) 87 | case token.QUO: 88 | e.stack.Push(x / y) 89 | case token.EQL: 90 | e.stack.Push(x == y) 91 | case token.NEQ: 92 | e.stack.Push(x != y) 93 | default: 94 | e.err = errors.Errorf("invalid operation '%s' at [%v]", n.Op, n.Pos()) 95 | return 96 | } 97 | } 98 | case string: 99 | switch y := y.(type) { 100 | case string: 101 | e.stack.Push(x + y) 102 | } 103 | } 104 | } 105 | 106 | func (e *evaluator) VisitUnaryExpression(n *ast.UnaryExpr) { 107 | ast.Walk(e, n.X) 108 | 109 | x := e.stack.Pop() 110 | 111 | switch x := x.(type) { 112 | case float64: 113 | switch n.Op { 114 | case token.SUB: 115 | e.stack.Push(-x) 116 | default: 117 | e.err = errors.Errorf("invalid operation '%s' at [%v]", n.Op, n.Pos()) 118 | return 119 | } 120 | case bool: 121 | switch n.Op { 122 | case token.NOT: 123 | e.stack.Push(!x) 124 | default: 125 | e.err = errors.Errorf("invalid operation '%s' at [%v]", n.Op, n.Pos()) 126 | } 127 | } 128 | } 129 | 130 | func (e *evaluator) VisitParenthesesExpression(n *ast.ParenExpr) { 131 | ast.Walk(e, n.X) 132 | } 133 | 134 | func (e *evaluator) VisitCallExpression(n *ast.CallExpr) { 135 | for _, arg := range n.Args { 136 | ast.Walk(e, arg) 137 | } 138 | ast.Walk(e, n.Fun) 139 | } 140 | 141 | func (e *evaluator) VisitIdentifier(n *ast.Ident) { 142 | if x, ok := e.identifiers[n.Name]; ok { 143 | switch x := x.(type) { 144 | case EvaluatorFunc: 145 | y := x(e.stack) 146 | e.stack.Push(y) 147 | default: 148 | e.stack.Push(x) 149 | } 150 | } else { 151 | e.err = errors.Errorf("unknown identifier '%s' at [%v]", n.Name, n.Pos()) 152 | } 153 | } 154 | 155 | func (e *evaluator) RegisterFunc(name string, f EvaluatorFunc) { 156 | e.identifiers[name] = f 157 | } 158 | 159 | func (e *evaluator) useCoreLibrary() { 160 | e.identifiers["true"] = true 161 | e.identifiers["false"] = false 162 | e.identifiers["Pi"] = math.Pi 163 | e.identifiers["E"] = math.E 164 | 165 | e.RegisterFunc("floor", func(s *Stack) interface{} { 166 | return math.Floor(s.Pop().(float64)) 167 | }) 168 | e.RegisterFunc("ceil", func(s *Stack) interface{} { 169 | return math.Ceil(s.Pop().(float64)) 170 | }) 171 | e.RegisterFunc("round", func(s *Stack) interface{} { 172 | return math.Round(s.Pop().(float64)) 173 | }) 174 | e.RegisterFunc("pow", func(s *Stack) interface{} { 175 | y := s.Pop().(float64) 176 | x := s.Pop().(float64) 177 | return math.Pow(x, y) 178 | }) 179 | e.RegisterFunc("sin", func(s *Stack) interface{} { 180 | return math.Sin(s.Pop().(float64)) 181 | }) 182 | e.RegisterFunc("cos", func(s *Stack) interface{} { 183 | return math.Cos(s.Pop().(float64)) 184 | }) 185 | } 186 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/README.md: -------------------------------------------------------------------------------- 1 | ## TOML parser and encoder for Go with reflection 2 | 3 | TOML stands for Tom's Obvious, Minimal Language. This Go package provides a 4 | reflection interface similar to Go's standard library `json` and `xml` 5 | packages. This package also supports the `encoding.TextUnmarshaler` and 6 | `encoding.TextMarshaler` interfaces so that you can define custom data 7 | representations. (There is an example of this below.) 8 | 9 | Spec: https://github.com/toml-lang/toml 10 | 11 | Compatible with TOML version 12 | [v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md) 13 | 14 | Documentation: https://godoc.org/github.com/BurntSushi/toml 15 | 16 | Installation: 17 | 18 | ```bash 19 | go get github.com/BurntSushi/toml 20 | ``` 21 | 22 | Try the toml validator: 23 | 24 | ```bash 25 | go get github.com/BurntSushi/toml/cmd/tomlv 26 | tomlv some-toml-file.toml 27 | ``` 28 | 29 | [![Build Status](https://travis-ci.org/BurntSushi/toml.svg?branch=master)](https://travis-ci.org/BurntSushi/toml) [![GoDoc](https://godoc.org/github.com/BurntSushi/toml?status.svg)](https://godoc.org/github.com/BurntSushi/toml) 30 | 31 | ### Testing 32 | 33 | This package passes all tests in 34 | [toml-test](https://github.com/BurntSushi/toml-test) for both the decoder 35 | and the encoder. 36 | 37 | ### Examples 38 | 39 | This package works similarly to how the Go standard library handles `XML` 40 | and `JSON`. Namely, data is loaded into Go values via reflection. 41 | 42 | For the simplest example, consider some TOML file as just a list of keys 43 | and values: 44 | 45 | ```toml 46 | Age = 25 47 | Cats = [ "Cauchy", "Plato" ] 48 | Pi = 3.14 49 | Perfection = [ 6, 28, 496, 8128 ] 50 | DOB = 1987-07-05T05:45:00Z 51 | ``` 52 | 53 | Which could be defined in Go as: 54 | 55 | ```go 56 | type Config struct { 57 | Age int 58 | Cats []string 59 | Pi float64 60 | Perfection []int 61 | DOB time.Time // requires `import time` 62 | } 63 | ``` 64 | 65 | And then decoded with: 66 | 67 | ```go 68 | var conf Config 69 | if _, err := toml.Decode(tomlData, &conf); err != nil { 70 | // handle error 71 | } 72 | ``` 73 | 74 | You can also use struct tags if your struct field name doesn't map to a TOML 75 | key value directly: 76 | 77 | ```toml 78 | some_key_NAME = "wat" 79 | ``` 80 | 81 | ```go 82 | type TOML struct { 83 | ObscureKey string `toml:"some_key_NAME"` 84 | } 85 | ``` 86 | 87 | ### Using the `encoding.TextUnmarshaler` interface 88 | 89 | Here's an example that automatically parses duration strings into 90 | `time.Duration` values: 91 | 92 | ```toml 93 | [[song]] 94 | name = "Thunder Road" 95 | duration = "4m49s" 96 | 97 | [[song]] 98 | name = "Stairway to Heaven" 99 | duration = "8m03s" 100 | ``` 101 | 102 | Which can be decoded with: 103 | 104 | ```go 105 | type song struct { 106 | Name string 107 | Duration duration 108 | } 109 | type songs struct { 110 | Song []song 111 | } 112 | var favorites songs 113 | if _, err := toml.Decode(blob, &favorites); err != nil { 114 | log.Fatal(err) 115 | } 116 | 117 | for _, s := range favorites.Song { 118 | fmt.Printf("%s (%s)\n", s.Name, s.Duration) 119 | } 120 | ``` 121 | 122 | And you'll also need a `duration` type that satisfies the 123 | `encoding.TextUnmarshaler` interface: 124 | 125 | ```go 126 | type duration struct { 127 | time.Duration 128 | } 129 | 130 | func (d *duration) UnmarshalText(text []byte) error { 131 | var err error 132 | d.Duration, err = time.ParseDuration(string(text)) 133 | return err 134 | } 135 | ``` 136 | 137 | ### More complex usage 138 | 139 | Here's an example of how to load the example from the official spec page: 140 | 141 | ```toml 142 | # This is a TOML document. Boom. 143 | 144 | title = "TOML Example" 145 | 146 | [owner] 147 | name = "Tom Preston-Werner" 148 | organization = "GitHub" 149 | bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." 150 | dob = 1979-05-27T07:32:00Z # First class dates? Why not? 151 | 152 | [database] 153 | server = "192.168.1.1" 154 | ports = [ 8001, 8001, 8002 ] 155 | connection_max = 5000 156 | enabled = true 157 | 158 | [servers] 159 | 160 | # You can indent as you please. Tabs or spaces. TOML don't care. 161 | [servers.alpha] 162 | ip = "10.0.0.1" 163 | dc = "eqdc10" 164 | 165 | [servers.beta] 166 | ip = "10.0.0.2" 167 | dc = "eqdc10" 168 | 169 | [clients] 170 | data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it 171 | 172 | # Line breaks are OK when inside arrays 173 | hosts = [ 174 | "alpha", 175 | "omega" 176 | ] 177 | ``` 178 | 179 | And the corresponding Go types are: 180 | 181 | ```go 182 | type tomlConfig struct { 183 | Title string 184 | Owner ownerInfo 185 | DB database `toml:"database"` 186 | Servers map[string]server 187 | Clients clients 188 | } 189 | 190 | type ownerInfo struct { 191 | Name string 192 | Org string `toml:"organization"` 193 | Bio string 194 | DOB time.Time 195 | } 196 | 197 | type database struct { 198 | Server string 199 | Ports []int 200 | ConnMax int `toml:"connection_max"` 201 | Enabled bool 202 | } 203 | 204 | type server struct { 205 | IP string 206 | DC string 207 | } 208 | 209 | type clients struct { 210 | Data [][]interface{} 211 | Hosts []string 212 | } 213 | ``` 214 | 215 | Note that a case insensitive match will be tried if an exact match can't be 216 | found. 217 | 218 | A working example of the above can be found in `_examples/example.{go,toml}`. 219 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/http_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httptest" 7 | "net/url" 8 | "strings" 9 | ) 10 | 11 | // httpCode is a helper that returns HTTP code of the response. It returns -1 and 12 | // an error if building a new request fails. 13 | func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) { 14 | w := httptest.NewRecorder() 15 | req, err := http.NewRequest(method, url, nil) 16 | if err != nil { 17 | return -1, err 18 | } 19 | req.URL.RawQuery = values.Encode() 20 | handler(w, req) 21 | return w.Code, nil 22 | } 23 | 24 | // HTTPSuccess asserts that a specified handler returns a success status code. 25 | // 26 | // assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) 27 | // 28 | // Returns whether the assertion was successful (true) or not (false). 29 | func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { 30 | if h, ok := t.(tHelper); ok { 31 | h.Helper() 32 | } 33 | code, err := httpCode(handler, method, url, values) 34 | if err != nil { 35 | Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) 36 | return false 37 | } 38 | 39 | isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent 40 | if !isSuccessCode { 41 | Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code)) 42 | } 43 | 44 | return isSuccessCode 45 | } 46 | 47 | // HTTPRedirect asserts that a specified handler returns a redirect status code. 48 | // 49 | // assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} 50 | // 51 | // Returns whether the assertion was successful (true) or not (false). 52 | func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { 53 | if h, ok := t.(tHelper); ok { 54 | h.Helper() 55 | } 56 | code, err := httpCode(handler, method, url, values) 57 | if err != nil { 58 | Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) 59 | return false 60 | } 61 | 62 | isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect 63 | if !isRedirectCode { 64 | Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code)) 65 | } 66 | 67 | return isRedirectCode 68 | } 69 | 70 | // HTTPError asserts that a specified handler returns an error status code. 71 | // 72 | // assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} 73 | // 74 | // Returns whether the assertion was successful (true) or not (false). 75 | func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { 76 | if h, ok := t.(tHelper); ok { 77 | h.Helper() 78 | } 79 | code, err := httpCode(handler, method, url, values) 80 | if err != nil { 81 | Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) 82 | return false 83 | } 84 | 85 | isErrorCode := code >= http.StatusBadRequest 86 | if !isErrorCode { 87 | Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code)) 88 | } 89 | 90 | return isErrorCode 91 | } 92 | 93 | // HTTPBody is a helper that returns HTTP body of the response. It returns 94 | // empty string if building a new request fails. 95 | func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { 96 | w := httptest.NewRecorder() 97 | req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) 98 | if err != nil { 99 | return "" 100 | } 101 | handler(w, req) 102 | return w.Body.String() 103 | } 104 | 105 | // HTTPBodyContains asserts that a specified handler returns a 106 | // body that contains a string. 107 | // 108 | // assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") 109 | // 110 | // Returns whether the assertion was successful (true) or not (false). 111 | func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { 112 | if h, ok := t.(tHelper); ok { 113 | h.Helper() 114 | } 115 | body := HTTPBody(handler, method, url, values) 116 | 117 | contains := strings.Contains(body, fmt.Sprint(str)) 118 | if !contains { 119 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) 120 | } 121 | 122 | return contains 123 | } 124 | 125 | // HTTPBodyNotContains asserts that a specified handler returns a 126 | // body that does not contain a string. 127 | // 128 | // assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") 129 | // 130 | // Returns whether the assertion was successful (true) or not (false). 131 | func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { 132 | if h, ok := t.(tHelper); ok { 133 | h.Helper() 134 | } 135 | body := HTTPBody(handler, method, url, values) 136 | 137 | contains := strings.Contains(body, fmt.Sprint(str)) 138 | if contains { 139 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) 140 | } 141 | 142 | return !contains 143 | } 144 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/yamlprivateh.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | const ( 4 | // The size of the input raw buffer. 5 | input_raw_buffer_size = 512 6 | 7 | // The size of the input buffer. 8 | // It should be possible to decode the whole raw buffer. 9 | input_buffer_size = input_raw_buffer_size * 3 10 | 11 | // The size of the output buffer. 12 | output_buffer_size = 128 13 | 14 | // The size of the output raw buffer. 15 | // It should be possible to encode the whole output buffer. 16 | output_raw_buffer_size = (output_buffer_size*2 + 2) 17 | 18 | // The size of other stacks and queues. 19 | initial_stack_size = 16 20 | initial_queue_size = 16 21 | initial_string_size = 16 22 | ) 23 | 24 | // Check if the character at the specified position is an alphabetical 25 | // character, a digit, '_', or '-'. 26 | func is_alpha(b []byte, i int) bool { 27 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-' 28 | } 29 | 30 | // Check if the character at the specified position is a digit. 31 | func is_digit(b []byte, i int) bool { 32 | return b[i] >= '0' && b[i] <= '9' 33 | } 34 | 35 | // Get the value of a digit. 36 | func as_digit(b []byte, i int) int { 37 | return int(b[i]) - '0' 38 | } 39 | 40 | // Check if the character at the specified position is a hex-digit. 41 | func is_hex(b []byte, i int) bool { 42 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f' 43 | } 44 | 45 | // Get the value of a hex-digit. 46 | func as_hex(b []byte, i int) int { 47 | bi := b[i] 48 | if bi >= 'A' && bi <= 'F' { 49 | return int(bi) - 'A' + 10 50 | } 51 | if bi >= 'a' && bi <= 'f' { 52 | return int(bi) - 'a' + 10 53 | } 54 | return int(bi) - '0' 55 | } 56 | 57 | // Check if the character is ASCII. 58 | func is_ascii(b []byte, i int) bool { 59 | return b[i] <= 0x7F 60 | } 61 | 62 | // Check if the character at the start of the buffer can be printed unescaped. 63 | func is_printable(b []byte, i int) bool { 64 | return ((b[i] == 0x0A) || // . == #x0A 65 | (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E 66 | (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF 67 | (b[i] > 0xC2 && b[i] < 0xED) || 68 | (b[i] == 0xED && b[i+1] < 0xA0) || 69 | (b[i] == 0xEE) || 70 | (b[i] == 0xEF && // #xE000 <= . <= #xFFFD 71 | !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF 72 | !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF)))) 73 | } 74 | 75 | // Check if the character at the specified position is NUL. 76 | func is_z(b []byte, i int) bool { 77 | return b[i] == 0x00 78 | } 79 | 80 | // Check if the beginning of the buffer is a BOM. 81 | func is_bom(b []byte, i int) bool { 82 | return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF 83 | } 84 | 85 | // Check if the character at the specified position is space. 86 | func is_space(b []byte, i int) bool { 87 | return b[i] == ' ' 88 | } 89 | 90 | // Check if the character at the specified position is tab. 91 | func is_tab(b []byte, i int) bool { 92 | return b[i] == '\t' 93 | } 94 | 95 | // Check if the character at the specified position is blank (space or tab). 96 | func is_blank(b []byte, i int) bool { 97 | //return is_space(b, i) || is_tab(b, i) 98 | return b[i] == ' ' || b[i] == '\t' 99 | } 100 | 101 | // Check if the character at the specified position is a line break. 102 | func is_break(b []byte, i int) bool { 103 | return (b[i] == '\r' || // CR (#xD) 104 | b[i] == '\n' || // LF (#xA) 105 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 106 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 107 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029) 108 | } 109 | 110 | func is_crlf(b []byte, i int) bool { 111 | return b[i] == '\r' && b[i+1] == '\n' 112 | } 113 | 114 | // Check if the character is a line break or NUL. 115 | func is_breakz(b []byte, i int) bool { 116 | //return is_break(b, i) || is_z(b, i) 117 | return ( // is_break: 118 | b[i] == '\r' || // CR (#xD) 119 | b[i] == '\n' || // LF (#xA) 120 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 121 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 122 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) 123 | // is_z: 124 | b[i] == 0) 125 | } 126 | 127 | // Check if the character is a line break, space, or NUL. 128 | func is_spacez(b []byte, i int) bool { 129 | //return is_space(b, i) || is_breakz(b, i) 130 | return ( // is_space: 131 | b[i] == ' ' || 132 | // is_breakz: 133 | b[i] == '\r' || // CR (#xD) 134 | b[i] == '\n' || // LF (#xA) 135 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 136 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 137 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) 138 | b[i] == 0) 139 | } 140 | 141 | // Check if the character is a line break, space, tab, or NUL. 142 | func is_blankz(b []byte, i int) bool { 143 | //return is_blank(b, i) || is_breakz(b, i) 144 | return ( // is_blank: 145 | b[i] == ' ' || b[i] == '\t' || 146 | // is_breakz: 147 | b[i] == '\r' || // CR (#xD) 148 | b[i] == '\n' || // LF (#xA) 149 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 150 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 151 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) 152 | b[i] == 0) 153 | } 154 | 155 | // Determine the width of the character. 156 | func width(b byte) int { 157 | // Don't replace these by a switch without first 158 | // confirming that it is being inlined. 159 | if b&0x80 == 0x00 { 160 | return 1 161 | } 162 | if b&0xE0 == 0xC0 { 163 | return 2 164 | } 165 | if b&0xF0 == 0xE0 { 166 | return 3 167 | } 168 | if b&0xF8 == 0xF0 { 169 | return 4 170 | } 171 | return 0 172 | 173 | } 174 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/map.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Dario Castañé. All rights reserved. 2 | // Copyright 2009 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // Based on src/pkg/reflect/deepequal.go from official 7 | // golang's stdlib. 8 | 9 | package mergo 10 | 11 | import ( 12 | "fmt" 13 | "reflect" 14 | "unicode" 15 | "unicode/utf8" 16 | ) 17 | 18 | func changeInitialCase(s string, mapper func(rune) rune) string { 19 | if s == "" { 20 | return s 21 | } 22 | r, n := utf8.DecodeRuneInString(s) 23 | return string(mapper(r)) + s[n:] 24 | } 25 | 26 | func isExported(field reflect.StructField) bool { 27 | r, _ := utf8.DecodeRuneInString(field.Name) 28 | return r >= 'A' && r <= 'Z' 29 | } 30 | 31 | // Traverses recursively both values, assigning src's fields values to dst. 32 | // The map argument tracks comparisons that have already been seen, which allows 33 | // short circuiting on recursive types. 34 | func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) { 35 | overwrite := config.Overwrite 36 | if dst.CanAddr() { 37 | addr := dst.UnsafeAddr() 38 | h := 17 * addr 39 | seen := visited[h] 40 | typ := dst.Type() 41 | for p := seen; p != nil; p = p.next { 42 | if p.ptr == addr && p.typ == typ { 43 | return nil 44 | } 45 | } 46 | // Remember, remember... 47 | visited[h] = &visit{addr, typ, seen} 48 | } 49 | zeroValue := reflect.Value{} 50 | switch dst.Kind() { 51 | case reflect.Map: 52 | dstMap := dst.Interface().(map[string]interface{}) 53 | for i, n := 0, src.NumField(); i < n; i++ { 54 | srcType := src.Type() 55 | field := srcType.Field(i) 56 | if !isExported(field) { 57 | continue 58 | } 59 | fieldName := field.Name 60 | fieldName = changeInitialCase(fieldName, unicode.ToLower) 61 | if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v)) || overwrite) { 62 | dstMap[fieldName] = src.Field(i).Interface() 63 | } 64 | } 65 | case reflect.Ptr: 66 | if dst.IsNil() { 67 | v := reflect.New(dst.Type().Elem()) 68 | dst.Set(v) 69 | } 70 | dst = dst.Elem() 71 | fallthrough 72 | case reflect.Struct: 73 | srcMap := src.Interface().(map[string]interface{}) 74 | for key := range srcMap { 75 | config.overwriteWithEmptyValue = true 76 | srcValue := srcMap[key] 77 | fieldName := changeInitialCase(key, unicode.ToUpper) 78 | dstElement := dst.FieldByName(fieldName) 79 | if dstElement == zeroValue { 80 | // We discard it because the field doesn't exist. 81 | continue 82 | } 83 | srcElement := reflect.ValueOf(srcValue) 84 | dstKind := dstElement.Kind() 85 | srcKind := srcElement.Kind() 86 | if srcKind == reflect.Ptr && dstKind != reflect.Ptr { 87 | srcElement = srcElement.Elem() 88 | srcKind = reflect.TypeOf(srcElement.Interface()).Kind() 89 | } else if dstKind == reflect.Ptr { 90 | // Can this work? I guess it can't. 91 | if srcKind != reflect.Ptr && srcElement.CanAddr() { 92 | srcPtr := srcElement.Addr() 93 | srcElement = reflect.ValueOf(srcPtr) 94 | srcKind = reflect.Ptr 95 | } 96 | } 97 | 98 | if !srcElement.IsValid() { 99 | continue 100 | } 101 | if srcKind == dstKind { 102 | if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil { 103 | return 104 | } 105 | } else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface { 106 | if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil { 107 | return 108 | } 109 | } else if srcKind == reflect.Map { 110 | if err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil { 111 | return 112 | } 113 | } else { 114 | return fmt.Errorf("type mismatch on %s field: found %v, expected %v", fieldName, srcKind, dstKind) 115 | } 116 | } 117 | } 118 | return 119 | } 120 | 121 | // Map sets fields' values in dst from src. 122 | // src can be a map with string keys or a struct. dst must be the opposite: 123 | // if src is a map, dst must be a valid pointer to struct. If src is a struct, 124 | // dst must be map[string]interface{}. 125 | // It won't merge unexported (private) fields and will do recursively 126 | // any exported field. 127 | // If dst is a map, keys will be src fields' names in lower camel case. 128 | // Missing key in src that doesn't match a field in dst will be skipped. This 129 | // doesn't apply if dst is a map. 130 | // This is separated method from Merge because it is cleaner and it keeps sane 131 | // semantics: merging equal types, mapping different (restricted) types. 132 | func Map(dst, src interface{}, opts ...func(*Config)) error { 133 | return _map(dst, src, opts...) 134 | } 135 | 136 | // MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overridden by 137 | // non-empty src attribute values. 138 | // Deprecated: Use Map(…) with WithOverride 139 | func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error { 140 | return _map(dst, src, append(opts, WithOverride)...) 141 | } 142 | 143 | func _map(dst, src interface{}, opts ...func(*Config)) error { 144 | var ( 145 | vDst, vSrc reflect.Value 146 | err error 147 | ) 148 | config := &Config{} 149 | 150 | for _, opt := range opts { 151 | opt(config) 152 | } 153 | 154 | if vDst, vSrc, err = resolveValues(dst, src); err != nil { 155 | return err 156 | } 157 | // To be friction-less, we redirect equal-type arguments 158 | // to deepMerge. Only because arguments can be anything. 159 | if vSrc.Kind() == vDst.Kind() { 160 | return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config) 161 | } 162 | switch vSrc.Kind() { 163 | case reflect.Struct: 164 | if vDst.Kind() != reflect.Map { 165 | return ErrExpectedMapAsDestination 166 | } 167 | case reflect.Map: 168 | if vDst.Kind() != reflect.Struct { 169 | return ErrExpectedStructAsDestination 170 | } 171 | default: 172 | return ErrNotSupported 173 | } 174 | return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config) 175 | } 176 | -------------------------------------------------------------------------------- /vendor/github.com/mitchellh/mapstructure/decode_hooks.go: -------------------------------------------------------------------------------- 1 | package mapstructure 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net" 7 | "reflect" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | // typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns 14 | // it into the proper DecodeHookFunc type, such as DecodeHookFuncType. 15 | func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { 16 | // Create variables here so we can reference them with the reflect pkg 17 | var f1 DecodeHookFuncType 18 | var f2 DecodeHookFuncKind 19 | 20 | // Fill in the variables into this interface and the rest is done 21 | // automatically using the reflect package. 22 | potential := []interface{}{f1, f2} 23 | 24 | v := reflect.ValueOf(h) 25 | vt := v.Type() 26 | for _, raw := range potential { 27 | pt := reflect.ValueOf(raw).Type() 28 | if vt.ConvertibleTo(pt) { 29 | return v.Convert(pt).Interface() 30 | } 31 | } 32 | 33 | return nil 34 | } 35 | 36 | // DecodeHookExec executes the given decode hook. This should be used 37 | // since it'll naturally degrade to the older backwards compatible DecodeHookFunc 38 | // that took reflect.Kind instead of reflect.Type. 39 | func DecodeHookExec( 40 | raw DecodeHookFunc, 41 | from reflect.Type, to reflect.Type, 42 | data interface{}) (interface{}, error) { 43 | switch f := typedDecodeHook(raw).(type) { 44 | case DecodeHookFuncType: 45 | return f(from, to, data) 46 | case DecodeHookFuncKind: 47 | return f(from.Kind(), to.Kind(), data) 48 | default: 49 | return nil, errors.New("invalid decode hook signature") 50 | } 51 | } 52 | 53 | // ComposeDecodeHookFunc creates a single DecodeHookFunc that 54 | // automatically composes multiple DecodeHookFuncs. 55 | // 56 | // The composed funcs are called in order, with the result of the 57 | // previous transformation. 58 | func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { 59 | return func( 60 | f reflect.Type, 61 | t reflect.Type, 62 | data interface{}) (interface{}, error) { 63 | var err error 64 | for _, f1 := range fs { 65 | data, err = DecodeHookExec(f1, f, t, data) 66 | if err != nil { 67 | return nil, err 68 | } 69 | 70 | // Modify the from kind to be correct with the new data 71 | f = nil 72 | if val := reflect.ValueOf(data); val.IsValid() { 73 | f = val.Type() 74 | } 75 | } 76 | 77 | return data, nil 78 | } 79 | } 80 | 81 | // StringToSliceHookFunc returns a DecodeHookFunc that converts 82 | // string to []string by splitting on the given sep. 83 | func StringToSliceHookFunc(sep string) DecodeHookFunc { 84 | return func( 85 | f reflect.Kind, 86 | t reflect.Kind, 87 | data interface{}) (interface{}, error) { 88 | if f != reflect.String || t != reflect.Slice { 89 | return data, nil 90 | } 91 | 92 | raw := data.(string) 93 | if raw == "" { 94 | return []string{}, nil 95 | } 96 | 97 | return strings.Split(raw, sep), nil 98 | } 99 | } 100 | 101 | // StringToTimeDurationHookFunc returns a DecodeHookFunc that converts 102 | // strings to time.Duration. 103 | func StringToTimeDurationHookFunc() DecodeHookFunc { 104 | return func( 105 | f reflect.Type, 106 | t reflect.Type, 107 | data interface{}) (interface{}, error) { 108 | if f.Kind() != reflect.String { 109 | return data, nil 110 | } 111 | if t != reflect.TypeOf(time.Duration(5)) { 112 | return data, nil 113 | } 114 | 115 | // Convert it by parsing 116 | return time.ParseDuration(data.(string)) 117 | } 118 | } 119 | 120 | // StringToIPHookFunc returns a DecodeHookFunc that converts 121 | // strings to net.IP 122 | func StringToIPHookFunc() DecodeHookFunc { 123 | return func( 124 | f reflect.Type, 125 | t reflect.Type, 126 | data interface{}) (interface{}, error) { 127 | if f.Kind() != reflect.String { 128 | return data, nil 129 | } 130 | if t != reflect.TypeOf(net.IP{}) { 131 | return data, nil 132 | } 133 | 134 | // Convert it by parsing 135 | ip := net.ParseIP(data.(string)) 136 | if ip == nil { 137 | return net.IP{}, fmt.Errorf("failed parsing ip %v", data) 138 | } 139 | 140 | return ip, nil 141 | } 142 | } 143 | 144 | // StringToIPNetHookFunc returns a DecodeHookFunc that converts 145 | // strings to net.IPNet 146 | func StringToIPNetHookFunc() DecodeHookFunc { 147 | return func( 148 | f reflect.Type, 149 | t reflect.Type, 150 | data interface{}) (interface{}, error) { 151 | if f.Kind() != reflect.String { 152 | return data, nil 153 | } 154 | if t != reflect.TypeOf(net.IPNet{}) { 155 | return data, nil 156 | } 157 | 158 | // Convert it by parsing 159 | _, net, err := net.ParseCIDR(data.(string)) 160 | return net, err 161 | } 162 | } 163 | 164 | // StringToTimeHookFunc returns a DecodeHookFunc that converts 165 | // strings to time.Time. 166 | func StringToTimeHookFunc(layout string) DecodeHookFunc { 167 | return func( 168 | f reflect.Type, 169 | t reflect.Type, 170 | data interface{}) (interface{}, error) { 171 | if f.Kind() != reflect.String { 172 | return data, nil 173 | } 174 | if t != reflect.TypeOf(time.Time{}) { 175 | return data, nil 176 | } 177 | 178 | // Convert it by parsing 179 | return time.Parse(layout, data.(string)) 180 | } 181 | } 182 | 183 | // WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to 184 | // the decoder. 185 | // 186 | // Note that this is significantly different from the WeaklyTypedInput option 187 | // of the DecoderConfig. 188 | func WeaklyTypedHook( 189 | f reflect.Kind, 190 | t reflect.Kind, 191 | data interface{}) (interface{}, error) { 192 | dataVal := reflect.ValueOf(data) 193 | switch t { 194 | case reflect.String: 195 | switch f { 196 | case reflect.Bool: 197 | if dataVal.Bool() { 198 | return "1", nil 199 | } 200 | return "0", nil 201 | case reflect.Float32: 202 | return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil 203 | case reflect.Int: 204 | return strconv.FormatInt(dataVal.Int(), 10), nil 205 | case reflect.Slice: 206 | dataType := dataVal.Type() 207 | elemKind := dataType.Elem().Kind() 208 | if elemKind == reflect.Uint8 { 209 | return string(dataVal.Interface().([]uint8)), nil 210 | } 211 | case reflect.Uint: 212 | return strconv.FormatUint(dataVal.Uint(), 10), nil 213 | } 214 | } 215 | 216 | return data, nil 217 | } 218 | -------------------------------------------------------------------------------- /id/id.go: -------------------------------------------------------------------------------- 1 | package id 2 | 3 | import ( 4 | "bytes" 5 | "encoding/base64" 6 | "net" 7 | "strconv" 8 | "sync" 9 | "time" 10 | 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | type ID int64 15 | 16 | type Generator struct { 17 | workerID uint16 18 | sequence uint16 19 | startTime int64 20 | lastTime int64 21 | mutex sync.Mutex 22 | } 23 | 24 | const ( 25 | bitLengthTimestamp = 37 26 | bitLengthWorkerID = 16 27 | bitLengthSequence = 10 28 | ) 29 | 30 | var ( 31 | ErrGenerateMachineID = errors.New("could not generate machine ID") 32 | ErrInvalidBase62Value = errors.New("invalid base62 value") 33 | ErrInvalidValue = errors.New("invalid value") 34 | 35 | base62Alphabet = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 36 | ) 37 | 38 | func NewGenerator(workerID uint16) *Generator { 39 | return NewGeneratorWithStartTime(workerID, time.Unix(0, 0)) 40 | } 41 | 42 | func NewGeneratorWithStartTime(workerID uint16, startTime time.Time) *Generator { 43 | return &Generator{ 44 | workerID: workerID, 45 | startTime: startTime.Unix(), 46 | mutex: sync.Mutex{}, 47 | } 48 | } 49 | 50 | func (g *Generator) Generate() ID { 51 | g.mutex.Lock() 52 | defer g.mutex.Unlock() 53 | 54 | g.lastTime = time.Now().Unix() - g.startTime 55 | 56 | value := Encode(g.lastTime, g.workerID, g.sequence) 57 | 58 | g.sequence++ 59 | 60 | if g.sequence >= (1 << bitLengthSequence) { 61 | g.sequence = 0 62 | 63 | time.Sleep(time.Second) 64 | } 65 | 66 | return value 67 | } 68 | 69 | func (g *Generator) GenerateList(size int) []ID { 70 | g.mutex.Lock() 71 | defer g.mutex.Unlock() 72 | 73 | list := make([]ID, size) 74 | g.lastTime = time.Now().Unix() - g.startTime 75 | 76 | for i := 0; i < size; i++ { 77 | list[i] = Encode(g.lastTime, g.workerID, g.sequence) 78 | 79 | g.sequence++ 80 | 81 | if g.sequence >= (1 << bitLengthSequence) { 82 | g.sequence = 0 83 | 84 | time.Sleep(time.Second) 85 | g.lastTime = time.Now().Unix() - g.startTime 86 | } 87 | } 88 | 89 | return list 90 | } 91 | 92 | func (i ID) Timestamp() int64 { 93 | return int64(i >> (bitLengthWorkerID + bitLengthSequence)) 94 | } 95 | 96 | func (i ID) WorkerID() uint16 { 97 | return uint16((i >> bitLengthSequence) & (1< 0 { 135 | data = append(data, byte(v&255)) 136 | v >>= 8 137 | } 138 | 139 | return base64.URLEncoding.EncodeToString(data) 140 | } 141 | 142 | func (i ID) Base62() string { 143 | if i <= 0 { 144 | panic(ErrInvalidValue.Error()) 145 | } 146 | 147 | v := int64(i) 148 | e := "" 149 | 150 | for v > 0 { 151 | e = string(base62Alphabet[v%int64(len(base62Alphabet))]) + e 152 | v /= int64(len(base62Alphabet)) 153 | } 154 | 155 | return string(e) 156 | } 157 | 158 | func Parse(s string) (ID, error) { 159 | i, err := strconv.ParseInt(s, 10, 64) 160 | if err != nil { 161 | return 0, err 162 | } 163 | if i <= 0 { 164 | return 0, ErrInvalidValue 165 | } 166 | return ID(i), nil 167 | } 168 | 169 | func ParseBase64(s string) (ID, error) { 170 | data, err := base64.URLEncoding.DecodeString(s) 171 | if err != nil { 172 | return 0, err 173 | } 174 | 175 | id := int64(0) 176 | for i, b := range data { 177 | id += int64(b) << (8 * uint64(i)) 178 | } 179 | 180 | if id <= 0 { 181 | return 0, ErrInvalidValue 182 | } 183 | 184 | return ID(id), nil 185 | } 186 | 187 | func ParseBase62(s string) (ID, error) { 188 | data := []rune(s) 189 | id := int64(0) 190 | 191 | for i := len(data) - 1; i >= 0; i-- { 192 | c := data[i] 193 | j := -1 194 | for k := 0; k < len(base62Alphabet); k++ { 195 | if base62Alphabet[k] == c { 196 | j = k 197 | break 198 | } 199 | } 200 | 201 | if j == -1 { 202 | return 0, ErrInvalidBase62Value 203 | } 204 | 205 | m := int64(len(data) - 1 - i) 206 | p := int64(1) 207 | for ; m > 0; m-- { 208 | p *= int64(len(base62Alphabet)) 209 | } 210 | 211 | id += int64(j) * p 212 | } 213 | 214 | if id <= 0 { 215 | return 0, ErrInvalidValue 216 | } 217 | 218 | return ID(id), nil 219 | } 220 | 221 | func Encode(timestamp int64, workerID uint16, sequence uint16) ID { 222 | if timestamp >= 1<= 1< 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is not running on Google App Engine, compiled by GopherJS, and 17 | // "-tags safe" is not added to the go build command line. The "disableunsafe" 18 | // tag is deprecated and thus should not be used. 19 | // +build !js,!appengine,!safe,!disableunsafe 20 | 21 | package spew 22 | 23 | import ( 24 | "reflect" 25 | "unsafe" 26 | ) 27 | 28 | const ( 29 | // UnsafeDisabled is a build-time constant which specifies whether or 30 | // not access to the unsafe package is available. 31 | UnsafeDisabled = false 32 | 33 | // ptrSize is the size of a pointer on the current arch. 34 | ptrSize = unsafe.Sizeof((*byte)(nil)) 35 | ) 36 | 37 | var ( 38 | // offsetPtr, offsetScalar, and offsetFlag are the offsets for the 39 | // internal reflect.Value fields. These values are valid before golang 40 | // commit ecccf07e7f9d which changed the format. The are also valid 41 | // after commit 82f48826c6c7 which changed the format again to mirror 42 | // the original format. Code in the init function updates these offsets 43 | // as necessary. 44 | offsetPtr = uintptr(ptrSize) 45 | offsetScalar = uintptr(0) 46 | offsetFlag = uintptr(ptrSize * 2) 47 | 48 | // flagKindWidth and flagKindShift indicate various bits that the 49 | // reflect package uses internally to track kind information. 50 | // 51 | // flagRO indicates whether or not the value field of a reflect.Value is 52 | // read-only. 53 | // 54 | // flagIndir indicates whether the value field of a reflect.Value is 55 | // the actual data or a pointer to the data. 56 | // 57 | // These values are valid before golang commit 90a7c3c86944 which 58 | // changed their positions. Code in the init function updates these 59 | // flags as necessary. 60 | flagKindWidth = uintptr(5) 61 | flagKindShift = uintptr(flagKindWidth - 1) 62 | flagRO = uintptr(1 << 0) 63 | flagIndir = uintptr(1 << 1) 64 | ) 65 | 66 | func init() { 67 | // Older versions of reflect.Value stored small integers directly in the 68 | // ptr field (which is named val in the older versions). Versions 69 | // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named 70 | // scalar for this purpose which unfortunately came before the flag 71 | // field, so the offset of the flag field is different for those 72 | // versions. 73 | // 74 | // This code constructs a new reflect.Value from a known small integer 75 | // and checks if the size of the reflect.Value struct indicates it has 76 | // the scalar field. When it does, the offsets are updated accordingly. 77 | vv := reflect.ValueOf(0xf00) 78 | if unsafe.Sizeof(vv) == (ptrSize * 4) { 79 | offsetScalar = ptrSize * 2 80 | offsetFlag = ptrSize * 3 81 | } 82 | 83 | // Commit 90a7c3c86944 changed the flag positions such that the low 84 | // order bits are the kind. This code extracts the kind from the flags 85 | // field and ensures it's the correct type. When it's not, the flag 86 | // order has been changed to the newer format, so the flags are updated 87 | // accordingly. 88 | upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) 89 | upfv := *(*uintptr)(upf) 90 | flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { 92 | flagKindShift = 0 93 | flagRO = 1 << 5 94 | flagIndir = 1 << 6 95 | 96 | // Commit adf9b30e5594 modified the flags to separate the 97 | // flagRO flag into two bits which specifies whether or not the 98 | // field is embedded. This causes flagIndir to move over a bit 99 | // and means that flagRO is the combination of either of the 100 | // original flagRO bit and the new bit. 101 | // 102 | // This code detects the change by extracting what used to be 103 | // the indirect bit to ensure it's set. When it's not, the flag 104 | // order has been changed to the newer format, so the flags are 105 | // updated accordingly. 106 | if upfv&flagIndir == 0 { 107 | flagRO = 3 << 5 108 | flagIndir = 1 << 7 109 | } 110 | } 111 | } 112 | 113 | // unsafeReflectValue converts the passed reflect.Value into a one that bypasses 114 | // the typical safety restrictions preventing access to unaddressable and 115 | // unexported data. It works by digging the raw pointer to the underlying 116 | // value out of the protected value and generating a new unprotected (unsafe) 117 | // reflect.Value to it. 118 | // 119 | // This allows us to check for implementations of the Stringer and error 120 | // interfaces to be used for pretty printing ordinarily unaddressable and 121 | // inaccessible values such as unexported struct fields. 122 | func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { 123 | indirects := 1 124 | vt := v.Type() 125 | upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) 126 | rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) 127 | if rvf&flagIndir != 0 { 128 | vt = reflect.PtrTo(v.Type()) 129 | indirects++ 130 | } else if offsetScalar != 0 { 131 | // The value is in the scalar field when it's not one of the 132 | // reference types. 133 | switch vt.Kind() { 134 | case reflect.Uintptr: 135 | case reflect.Chan: 136 | case reflect.Func: 137 | case reflect.Map: 138 | case reflect.Ptr: 139 | case reflect.UnsafePointer: 140 | default: 141 | upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + 142 | offsetScalar) 143 | } 144 | } 145 | 146 | pv := reflect.NewAt(vt, upv) 147 | rv = pv 148 | for i := 0; i < indirects; i++ { 149 | rv = rv.Elem() 150 | } 151 | return rv 152 | } 153 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/spew.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2016 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | ) 23 | 24 | // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were 25 | // passed with a default Formatter interface returned by NewFormatter. It 26 | // returns the formatted string as a value that satisfies error. See 27 | // NewFormatter for formatting details. 28 | // 29 | // This function is shorthand for the following syntax: 30 | // 31 | // fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 32 | func Errorf(format string, a ...interface{}) (err error) { 33 | return fmt.Errorf(format, convertArgs(a)...) 34 | } 35 | 36 | // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were 37 | // passed with a default Formatter interface returned by NewFormatter. It 38 | // returns the number of bytes written and any write error encountered. See 39 | // NewFormatter for formatting details. 40 | // 41 | // This function is shorthand for the following syntax: 42 | // 43 | // fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) 44 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) { 45 | return fmt.Fprint(w, convertArgs(a)...) 46 | } 47 | 48 | // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were 49 | // passed with a default Formatter interface returned by NewFormatter. It 50 | // returns the number of bytes written and any write error encountered. See 51 | // NewFormatter for formatting details. 52 | // 53 | // This function is shorthand for the following syntax: 54 | // 55 | // fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) 56 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { 57 | return fmt.Fprintf(w, format, convertArgs(a)...) 58 | } 59 | 60 | // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it 61 | // passed with a default Formatter interface returned by NewFormatter. See 62 | // NewFormatter for formatting details. 63 | // 64 | // This function is shorthand for the following syntax: 65 | // 66 | // fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) 67 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { 68 | return fmt.Fprintln(w, convertArgs(a)...) 69 | } 70 | 71 | // Print is a wrapper for fmt.Print that treats each argument as if it were 72 | // passed with a default Formatter interface returned by NewFormatter. It 73 | // returns the number of bytes written and any write error encountered. See 74 | // NewFormatter for formatting details. 75 | // 76 | // This function is shorthand for the following syntax: 77 | // 78 | // fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) 79 | func Print(a ...interface{}) (n int, err error) { 80 | return fmt.Print(convertArgs(a)...) 81 | } 82 | 83 | // Printf is a wrapper for fmt.Printf that treats each argument as if it were 84 | // passed with a default Formatter interface returned by NewFormatter. It 85 | // returns the number of bytes written and any write error encountered. See 86 | // NewFormatter for formatting details. 87 | // 88 | // This function is shorthand for the following syntax: 89 | // 90 | // fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 91 | func Printf(format string, a ...interface{}) (n int, err error) { 92 | return fmt.Printf(format, convertArgs(a)...) 93 | } 94 | 95 | // Println is a wrapper for fmt.Println that treats each argument as if it were 96 | // passed with a default Formatter interface returned by NewFormatter. It 97 | // returns the number of bytes written and any write error encountered. See 98 | // NewFormatter for formatting details. 99 | // 100 | // This function is shorthand for the following syntax: 101 | // 102 | // fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) 103 | func Println(a ...interface{}) (n int, err error) { 104 | return fmt.Println(convertArgs(a)...) 105 | } 106 | 107 | // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were 108 | // passed with a default Formatter interface returned by NewFormatter. It 109 | // returns the resulting string. See NewFormatter for formatting details. 110 | // 111 | // This function is shorthand for the following syntax: 112 | // 113 | // fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) 114 | func Sprint(a ...interface{}) string { 115 | return fmt.Sprint(convertArgs(a)...) 116 | } 117 | 118 | // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were 119 | // passed with a default Formatter interface returned by NewFormatter. It 120 | // returns the resulting string. See NewFormatter for formatting details. 121 | // 122 | // This function is shorthand for the following syntax: 123 | // 124 | // fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 125 | func Sprintf(format string, a ...interface{}) string { 126 | return fmt.Sprintf(format, convertArgs(a)...) 127 | } 128 | 129 | // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it 130 | // were passed with a default Formatter interface returned by NewFormatter. It 131 | // returns the resulting string. See NewFormatter for formatting details. 132 | // 133 | // This function is shorthand for the following syntax: 134 | // 135 | // fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) 136 | func Sprintln(a ...interface{}) string { 137 | return fmt.Sprintln(convertArgs(a)...) 138 | } 139 | 140 | // convertArgs accepts a slice of arguments and returns a slice of the same 141 | // length with each argument converted to a default spew Formatter interface. 142 | func convertArgs(args []interface{}) (formatters []interface{}) { 143 | formatters = make([]interface{}, len(args)) 144 | for index, arg := range args { 145 | formatters[index] = NewFormatter(arg) 146 | } 147 | return formatters 148 | } 149 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/scrypt/scrypt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package scrypt implements the scrypt key derivation function as defined in 6 | // Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard 7 | // Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf). 8 | package scrypt // import "golang.org/x/crypto/scrypt" 9 | 10 | import ( 11 | "crypto/sha256" 12 | "errors" 13 | 14 | "golang.org/x/crypto/pbkdf2" 15 | ) 16 | 17 | const maxInt = int(^uint(0) >> 1) 18 | 19 | // blockCopy copies n numbers from src into dst. 20 | func blockCopy(dst, src []uint32, n int) { 21 | copy(dst, src[:n]) 22 | } 23 | 24 | // blockXOR XORs numbers from dst with n numbers from src. 25 | func blockXOR(dst, src []uint32, n int) { 26 | for i, v := range src[:n] { 27 | dst[i] ^= v 28 | } 29 | } 30 | 31 | // salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in, 32 | // and puts the result into both tmp and out. 33 | func salsaXOR(tmp *[16]uint32, in, out []uint32) { 34 | w0 := tmp[0] ^ in[0] 35 | w1 := tmp[1] ^ in[1] 36 | w2 := tmp[2] ^ in[2] 37 | w3 := tmp[3] ^ in[3] 38 | w4 := tmp[4] ^ in[4] 39 | w5 := tmp[5] ^ in[5] 40 | w6 := tmp[6] ^ in[6] 41 | w7 := tmp[7] ^ in[7] 42 | w8 := tmp[8] ^ in[8] 43 | w9 := tmp[9] ^ in[9] 44 | w10 := tmp[10] ^ in[10] 45 | w11 := tmp[11] ^ in[11] 46 | w12 := tmp[12] ^ in[12] 47 | w13 := tmp[13] ^ in[13] 48 | w14 := tmp[14] ^ in[14] 49 | w15 := tmp[15] ^ in[15] 50 | 51 | x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8 52 | x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15 53 | 54 | for i := 0; i < 8; i += 2 { 55 | u := x0 + x12 56 | x4 ^= u<<7 | u>>(32-7) 57 | u = x4 + x0 58 | x8 ^= u<<9 | u>>(32-9) 59 | u = x8 + x4 60 | x12 ^= u<<13 | u>>(32-13) 61 | u = x12 + x8 62 | x0 ^= u<<18 | u>>(32-18) 63 | 64 | u = x5 + x1 65 | x9 ^= u<<7 | u>>(32-7) 66 | u = x9 + x5 67 | x13 ^= u<<9 | u>>(32-9) 68 | u = x13 + x9 69 | x1 ^= u<<13 | u>>(32-13) 70 | u = x1 + x13 71 | x5 ^= u<<18 | u>>(32-18) 72 | 73 | u = x10 + x6 74 | x14 ^= u<<7 | u>>(32-7) 75 | u = x14 + x10 76 | x2 ^= u<<9 | u>>(32-9) 77 | u = x2 + x14 78 | x6 ^= u<<13 | u>>(32-13) 79 | u = x6 + x2 80 | x10 ^= u<<18 | u>>(32-18) 81 | 82 | u = x15 + x11 83 | x3 ^= u<<7 | u>>(32-7) 84 | u = x3 + x15 85 | x7 ^= u<<9 | u>>(32-9) 86 | u = x7 + x3 87 | x11 ^= u<<13 | u>>(32-13) 88 | u = x11 + x7 89 | x15 ^= u<<18 | u>>(32-18) 90 | 91 | u = x0 + x3 92 | x1 ^= u<<7 | u>>(32-7) 93 | u = x1 + x0 94 | x2 ^= u<<9 | u>>(32-9) 95 | u = x2 + x1 96 | x3 ^= u<<13 | u>>(32-13) 97 | u = x3 + x2 98 | x0 ^= u<<18 | u>>(32-18) 99 | 100 | u = x5 + x4 101 | x6 ^= u<<7 | u>>(32-7) 102 | u = x6 + x5 103 | x7 ^= u<<9 | u>>(32-9) 104 | u = x7 + x6 105 | x4 ^= u<<13 | u>>(32-13) 106 | u = x4 + x7 107 | x5 ^= u<<18 | u>>(32-18) 108 | 109 | u = x10 + x9 110 | x11 ^= u<<7 | u>>(32-7) 111 | u = x11 + x10 112 | x8 ^= u<<9 | u>>(32-9) 113 | u = x8 + x11 114 | x9 ^= u<<13 | u>>(32-13) 115 | u = x9 + x8 116 | x10 ^= u<<18 | u>>(32-18) 117 | 118 | u = x15 + x14 119 | x12 ^= u<<7 | u>>(32-7) 120 | u = x12 + x15 121 | x13 ^= u<<9 | u>>(32-9) 122 | u = x13 + x12 123 | x14 ^= u<<13 | u>>(32-13) 124 | u = x14 + x13 125 | x15 ^= u<<18 | u>>(32-18) 126 | } 127 | x0 += w0 128 | x1 += w1 129 | x2 += w2 130 | x3 += w3 131 | x4 += w4 132 | x5 += w5 133 | x6 += w6 134 | x7 += w7 135 | x8 += w8 136 | x9 += w9 137 | x10 += w10 138 | x11 += w11 139 | x12 += w12 140 | x13 += w13 141 | x14 += w14 142 | x15 += w15 143 | 144 | out[0], tmp[0] = x0, x0 145 | out[1], tmp[1] = x1, x1 146 | out[2], tmp[2] = x2, x2 147 | out[3], tmp[3] = x3, x3 148 | out[4], tmp[4] = x4, x4 149 | out[5], tmp[5] = x5, x5 150 | out[6], tmp[6] = x6, x6 151 | out[7], tmp[7] = x7, x7 152 | out[8], tmp[8] = x8, x8 153 | out[9], tmp[9] = x9, x9 154 | out[10], tmp[10] = x10, x10 155 | out[11], tmp[11] = x11, x11 156 | out[12], tmp[12] = x12, x12 157 | out[13], tmp[13] = x13, x13 158 | out[14], tmp[14] = x14, x14 159 | out[15], tmp[15] = x15, x15 160 | } 161 | 162 | func blockMix(tmp *[16]uint32, in, out []uint32, r int) { 163 | blockCopy(tmp[:], in[(2*r-1)*16:], 16) 164 | for i := 0; i < 2*r; i += 2 { 165 | salsaXOR(tmp, in[i*16:], out[i*8:]) 166 | salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:]) 167 | } 168 | } 169 | 170 | func integer(b []uint32, r int) uint64 { 171 | j := (2*r - 1) * 16 172 | return uint64(b[j]) | uint64(b[j+1])<<32 173 | } 174 | 175 | func smix(b []byte, r, N int, v, xy []uint32) { 176 | var tmp [16]uint32 177 | x := xy 178 | y := xy[32*r:] 179 | 180 | j := 0 181 | for i := 0; i < 32*r; i++ { 182 | x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24 183 | j += 4 184 | } 185 | for i := 0; i < N; i += 2 { 186 | blockCopy(v[i*(32*r):], x, 32*r) 187 | blockMix(&tmp, x, y, r) 188 | 189 | blockCopy(v[(i+1)*(32*r):], y, 32*r) 190 | blockMix(&tmp, y, x, r) 191 | } 192 | for i := 0; i < N; i += 2 { 193 | j := int(integer(x, r) & uint64(N-1)) 194 | blockXOR(x, v[j*(32*r):], 32*r) 195 | blockMix(&tmp, x, y, r) 196 | 197 | j = int(integer(y, r) & uint64(N-1)) 198 | blockXOR(y, v[j*(32*r):], 32*r) 199 | blockMix(&tmp, y, x, r) 200 | } 201 | j = 0 202 | for _, v := range x[:32*r] { 203 | b[j+0] = byte(v >> 0) 204 | b[j+1] = byte(v >> 8) 205 | b[j+2] = byte(v >> 16) 206 | b[j+3] = byte(v >> 24) 207 | j += 4 208 | } 209 | } 210 | 211 | // Key derives a key from the password, salt, and cost parameters, returning 212 | // a byte slice of length keyLen that can be used as cryptographic key. 213 | // 214 | // N is a CPU/memory cost parameter, which must be a power of two greater than 1. 215 | // r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the 216 | // limits, the function returns a nil byte slice and an error. 217 | // 218 | // For example, you can get a derived key for e.g. AES-256 (which needs a 219 | // 32-byte key) by doing: 220 | // 221 | // dk, err := scrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32) 222 | // 223 | // The recommended parameters for interactive logins as of 2017 are N=32768, r=8 224 | // and p=1. The parameters N, r, and p should be increased as memory latency and 225 | // CPU parallelism increases; consider setting N to the highest power of 2 you 226 | // can derive within 100 milliseconds. Remember to get a good random salt. 227 | func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) { 228 | if N <= 1 || N&(N-1) != 0 { 229 | return nil, errors.New("scrypt: N must be > 1 and a power of 2") 230 | } 231 | if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r { 232 | return nil, errors.New("scrypt: parameters are too large") 233 | } 234 | 235 | xy := make([]uint32, 64*r) 236 | v := make([]uint32, 32*N*r) 237 | b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New) 238 | 239 | for i := 0; i < p; i++ { 240 | smix(b[i*128*r:], r, N, v, xy) 241 | } 242 | 243 | return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil 244 | } 245 | -------------------------------------------------------------------------------- /vendor/github.com/BurntSushi/toml/type_fields.go: -------------------------------------------------------------------------------- 1 | package toml 2 | 3 | // Struct field handling is adapted from code in encoding/json: 4 | // 5 | // Copyright 2010 The Go Authors. All rights reserved. 6 | // Use of this source code is governed by a BSD-style 7 | // license that can be found in the Go distribution. 8 | 9 | import ( 10 | "reflect" 11 | "sort" 12 | "sync" 13 | ) 14 | 15 | // A field represents a single field found in a struct. 16 | type field struct { 17 | name string // the name of the field (`toml` tag included) 18 | tag bool // whether field has a `toml` tag 19 | index []int // represents the depth of an anonymous field 20 | typ reflect.Type // the type of the field 21 | } 22 | 23 | // byName sorts field by name, breaking ties with depth, 24 | // then breaking ties with "name came from toml tag", then 25 | // breaking ties with index sequence. 26 | type byName []field 27 | 28 | func (x byName) Len() int { return len(x) } 29 | 30 | func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 31 | 32 | func (x byName) Less(i, j int) bool { 33 | if x[i].name != x[j].name { 34 | return x[i].name < x[j].name 35 | } 36 | if len(x[i].index) != len(x[j].index) { 37 | return len(x[i].index) < len(x[j].index) 38 | } 39 | if x[i].tag != x[j].tag { 40 | return x[i].tag 41 | } 42 | return byIndex(x).Less(i, j) 43 | } 44 | 45 | // byIndex sorts field by index sequence. 46 | type byIndex []field 47 | 48 | func (x byIndex) Len() int { return len(x) } 49 | 50 | func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 51 | 52 | func (x byIndex) Less(i, j int) bool { 53 | for k, xik := range x[i].index { 54 | if k >= len(x[j].index) { 55 | return false 56 | } 57 | if xik != x[j].index[k] { 58 | return xik < x[j].index[k] 59 | } 60 | } 61 | return len(x[i].index) < len(x[j].index) 62 | } 63 | 64 | // typeFields returns a list of fields that TOML should recognize for the given 65 | // type. The algorithm is breadth-first search over the set of structs to 66 | // include - the top struct and then any reachable anonymous structs. 67 | func typeFields(t reflect.Type) []field { 68 | // Anonymous fields to explore at the current level and the next. 69 | current := []field{} 70 | next := []field{{typ: t}} 71 | 72 | // Count of queued names for current level and the next. 73 | count := map[reflect.Type]int{} 74 | nextCount := map[reflect.Type]int{} 75 | 76 | // Types already visited at an earlier level. 77 | visited := map[reflect.Type]bool{} 78 | 79 | // Fields found. 80 | var fields []field 81 | 82 | for len(next) > 0 { 83 | current, next = next, current[:0] 84 | count, nextCount = nextCount, map[reflect.Type]int{} 85 | 86 | for _, f := range current { 87 | if visited[f.typ] { 88 | continue 89 | } 90 | visited[f.typ] = true 91 | 92 | // Scan f.typ for fields to include. 93 | for i := 0; i < f.typ.NumField(); i++ { 94 | sf := f.typ.Field(i) 95 | if sf.PkgPath != "" && !sf.Anonymous { // unexported 96 | continue 97 | } 98 | opts := getOptions(sf.Tag) 99 | if opts.skip { 100 | continue 101 | } 102 | index := make([]int, len(f.index)+1) 103 | copy(index, f.index) 104 | index[len(f.index)] = i 105 | 106 | ft := sf.Type 107 | if ft.Name() == "" && ft.Kind() == reflect.Ptr { 108 | // Follow pointer. 109 | ft = ft.Elem() 110 | } 111 | 112 | // Record found field and index sequence. 113 | if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { 114 | tagged := opts.name != "" 115 | name := opts.name 116 | if name == "" { 117 | name = sf.Name 118 | } 119 | fields = append(fields, field{name, tagged, index, ft}) 120 | if count[f.typ] > 1 { 121 | // If there were multiple instances, add a second, 122 | // so that the annihilation code will see a duplicate. 123 | // It only cares about the distinction between 1 or 2, 124 | // so don't bother generating any more copies. 125 | fields = append(fields, fields[len(fields)-1]) 126 | } 127 | continue 128 | } 129 | 130 | // Record new anonymous struct to explore in next round. 131 | nextCount[ft]++ 132 | if nextCount[ft] == 1 { 133 | f := field{name: ft.Name(), index: index, typ: ft} 134 | next = append(next, f) 135 | } 136 | } 137 | } 138 | } 139 | 140 | sort.Sort(byName(fields)) 141 | 142 | // Delete all fields that are hidden by the Go rules for embedded fields, 143 | // except that fields with TOML tags are promoted. 144 | 145 | // The fields are sorted in primary order of name, secondary order 146 | // of field index length. Loop over names; for each name, delete 147 | // hidden fields by choosing the one dominant field that survives. 148 | out := fields[:0] 149 | for advance, i := 0, 0; i < len(fields); i += advance { 150 | // One iteration per name. 151 | // Find the sequence of fields with the name of this first field. 152 | fi := fields[i] 153 | name := fi.name 154 | for advance = 1; i+advance < len(fields); advance++ { 155 | fj := fields[i+advance] 156 | if fj.name != name { 157 | break 158 | } 159 | } 160 | if advance == 1 { // Only one field with this name 161 | out = append(out, fi) 162 | continue 163 | } 164 | dominant, ok := dominantField(fields[i : i+advance]) 165 | if ok { 166 | out = append(out, dominant) 167 | } 168 | } 169 | 170 | fields = out 171 | sort.Sort(byIndex(fields)) 172 | 173 | return fields 174 | } 175 | 176 | // dominantField looks through the fields, all of which are known to 177 | // have the same name, to find the single field that dominates the 178 | // others using Go's embedding rules, modified by the presence of 179 | // TOML tags. If there are multiple top-level fields, the boolean 180 | // will be false: This condition is an error in Go and we skip all 181 | // the fields. 182 | func dominantField(fields []field) (field, bool) { 183 | // The fields are sorted in increasing index-length order. The winner 184 | // must therefore be one with the shortest index length. Drop all 185 | // longer entries, which is easy: just truncate the slice. 186 | length := len(fields[0].index) 187 | tagged := -1 // Index of first tagged field. 188 | for i, f := range fields { 189 | if len(f.index) > length { 190 | fields = fields[:i] 191 | break 192 | } 193 | if f.tag { 194 | if tagged >= 0 { 195 | // Multiple tagged fields at the same level: conflict. 196 | // Return no field. 197 | return field{}, false 198 | } 199 | tagged = i 200 | } 201 | } 202 | if tagged >= 0 { 203 | return fields[tagged], true 204 | } 205 | // All remaining fields have the same length. If there's more than one, 206 | // we have a conflict (two fields named "X" at the same level) and we 207 | // return no field. 208 | if len(fields) > 1 { 209 | return field{}, false 210 | } 211 | return fields[0], true 212 | } 213 | 214 | var fieldCache struct { 215 | sync.RWMutex 216 | m map[reflect.Type][]field 217 | } 218 | 219 | // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. 220 | func cachedTypeFields(t reflect.Type) []field { 221 | fieldCache.RLock() 222 | f := fieldCache.m[t] 223 | fieldCache.RUnlock() 224 | if f != nil { 225 | return f 226 | } 227 | 228 | // Compute fields without lock. 229 | // Might duplicate effort but won't hold other computations back. 230 | f = typeFields(t) 231 | if f == nil { 232 | f = []field{} 233 | } 234 | 235 | fieldCache.Lock() 236 | if fieldCache.m == nil { 237 | fieldCache.m = map[reflect.Type][]field{} 238 | } 239 | fieldCache.m[t] = f 240 | fieldCache.Unlock() 241 | return f 242 | } 243 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/resolve.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "encoding/base64" 5 | "math" 6 | "regexp" 7 | "strconv" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | type resolveMapItem struct { 13 | value interface{} 14 | tag string 15 | } 16 | 17 | var resolveTable = make([]byte, 256) 18 | var resolveMap = make(map[string]resolveMapItem) 19 | 20 | func init() { 21 | t := resolveTable 22 | t[int('+')] = 'S' // Sign 23 | t[int('-')] = 'S' 24 | for _, c := range "0123456789" { 25 | t[int(c)] = 'D' // Digit 26 | } 27 | for _, c := range "yYnNtTfFoO~" { 28 | t[int(c)] = 'M' // In map 29 | } 30 | t[int('.')] = '.' // Float (potentially in map) 31 | 32 | var resolveMapList = []struct { 33 | v interface{} 34 | tag string 35 | l []string 36 | }{ 37 | {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}}, 38 | {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}}, 39 | {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}}, 40 | {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}}, 41 | {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}}, 42 | {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}}, 43 | {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}}, 44 | {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}}, 45 | {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}}, 46 | {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}}, 47 | {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}}, 48 | {"<<", yaml_MERGE_TAG, []string{"<<"}}, 49 | } 50 | 51 | m := resolveMap 52 | for _, item := range resolveMapList { 53 | for _, s := range item.l { 54 | m[s] = resolveMapItem{item.v, item.tag} 55 | } 56 | } 57 | } 58 | 59 | const longTagPrefix = "tag:yaml.org,2002:" 60 | 61 | func shortTag(tag string) string { 62 | // TODO This can easily be made faster and produce less garbage. 63 | if strings.HasPrefix(tag, longTagPrefix) { 64 | return "!!" + tag[len(longTagPrefix):] 65 | } 66 | return tag 67 | } 68 | 69 | func longTag(tag string) string { 70 | if strings.HasPrefix(tag, "!!") { 71 | return longTagPrefix + tag[2:] 72 | } 73 | return tag 74 | } 75 | 76 | func resolvableTag(tag string) bool { 77 | switch tag { 78 | case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG: 79 | return true 80 | } 81 | return false 82 | } 83 | 84 | var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`) 85 | 86 | func resolve(tag string, in string) (rtag string, out interface{}) { 87 | if !resolvableTag(tag) { 88 | return tag, in 89 | } 90 | 91 | defer func() { 92 | switch tag { 93 | case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG: 94 | return 95 | case yaml_FLOAT_TAG: 96 | if rtag == yaml_INT_TAG { 97 | switch v := out.(type) { 98 | case int64: 99 | rtag = yaml_FLOAT_TAG 100 | out = float64(v) 101 | return 102 | case int: 103 | rtag = yaml_FLOAT_TAG 104 | out = float64(v) 105 | return 106 | } 107 | } 108 | } 109 | failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) 110 | }() 111 | 112 | // Any data is accepted as a !!str or !!binary. 113 | // Otherwise, the prefix is enough of a hint about what it might be. 114 | hint := byte('N') 115 | if in != "" { 116 | hint = resolveTable[in[0]] 117 | } 118 | if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG { 119 | // Handle things we can lookup in a map. 120 | if item, ok := resolveMap[in]; ok { 121 | return item.tag, item.value 122 | } 123 | 124 | // Base 60 floats are a bad idea, were dropped in YAML 1.2, and 125 | // are purposefully unsupported here. They're still quoted on 126 | // the way out for compatibility with other parser, though. 127 | 128 | switch hint { 129 | case 'M': 130 | // We've already checked the map above. 131 | 132 | case '.': 133 | // Not in the map, so maybe a normal float. 134 | floatv, err := strconv.ParseFloat(in, 64) 135 | if err == nil { 136 | return yaml_FLOAT_TAG, floatv 137 | } 138 | 139 | case 'D', 'S': 140 | // Int, float, or timestamp. 141 | // Only try values as a timestamp if the value is unquoted or there's an explicit 142 | // !!timestamp tag. 143 | if tag == "" || tag == yaml_TIMESTAMP_TAG { 144 | t, ok := parseTimestamp(in) 145 | if ok { 146 | return yaml_TIMESTAMP_TAG, t 147 | } 148 | } 149 | 150 | plain := strings.Replace(in, "_", "", -1) 151 | intv, err := strconv.ParseInt(plain, 0, 64) 152 | if err == nil { 153 | if intv == int64(int(intv)) { 154 | return yaml_INT_TAG, int(intv) 155 | } else { 156 | return yaml_INT_TAG, intv 157 | } 158 | } 159 | uintv, err := strconv.ParseUint(plain, 0, 64) 160 | if err == nil { 161 | return yaml_INT_TAG, uintv 162 | } 163 | if yamlStyleFloat.MatchString(plain) { 164 | floatv, err := strconv.ParseFloat(plain, 64) 165 | if err == nil { 166 | return yaml_FLOAT_TAG, floatv 167 | } 168 | } 169 | if strings.HasPrefix(plain, "0b") { 170 | intv, err := strconv.ParseInt(plain[2:], 2, 64) 171 | if err == nil { 172 | if intv == int64(int(intv)) { 173 | return yaml_INT_TAG, int(intv) 174 | } else { 175 | return yaml_INT_TAG, intv 176 | } 177 | } 178 | uintv, err := strconv.ParseUint(plain[2:], 2, 64) 179 | if err == nil { 180 | return yaml_INT_TAG, uintv 181 | } 182 | } else if strings.HasPrefix(plain, "-0b") { 183 | intv, err := strconv.ParseInt("-" + plain[3:], 2, 64) 184 | if err == nil { 185 | if true || intv == int64(int(intv)) { 186 | return yaml_INT_TAG, int(intv) 187 | } else { 188 | return yaml_INT_TAG, intv 189 | } 190 | } 191 | } 192 | default: 193 | panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")") 194 | } 195 | } 196 | return yaml_STR_TAG, in 197 | } 198 | 199 | // encodeBase64 encodes s as base64 that is broken up into multiple lines 200 | // as appropriate for the resulting length. 201 | func encodeBase64(s string) string { 202 | const lineLen = 70 203 | encLen := base64.StdEncoding.EncodedLen(len(s)) 204 | lines := encLen/lineLen + 1 205 | buf := make([]byte, encLen*2+lines) 206 | in := buf[0:encLen] 207 | out := buf[encLen:] 208 | base64.StdEncoding.Encode(in, []byte(s)) 209 | k := 0 210 | for i := 0; i < len(in); i += lineLen { 211 | j := i + lineLen 212 | if j > len(in) { 213 | j = len(in) 214 | } 215 | k += copy(out[k:], in[i:j]) 216 | if lines > 1 { 217 | out[k] = '\n' 218 | k++ 219 | } 220 | } 221 | return string(out[:k]) 222 | } 223 | 224 | // This is a subset of the formats allowed by the regular expression 225 | // defined at http://yaml.org/type/timestamp.html. 226 | var allowedTimestampFormats = []string{ 227 | "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields. 228 | "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t". 229 | "2006-1-2 15:4:5.999999999", // space separated with no time zone 230 | "2006-1-2", // date only 231 | // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5" 232 | // from the set of examples. 233 | } 234 | 235 | // parseTimestamp parses s as a timestamp string and 236 | // returns the timestamp and reports whether it succeeded. 237 | // Timestamp formats are defined at http://yaml.org/type/timestamp.html 238 | func parseTimestamp(s string) (time.Time, bool) { 239 | // TODO write code to check all the formats supported by 240 | // http://yaml.org/type/timestamp.html instead of using time.Parse. 241 | 242 | // Quick check: all date formats start with YYYY-. 243 | i := 0 244 | for ; i < len(s); i++ { 245 | if c := s[i]; c < '0' || c > '9' { 246 | break 247 | } 248 | } 249 | if i != 4 || i == len(s) || s[i] != '-' { 250 | return time.Time{}, false 251 | } 252 | for _, format := range allowedTimestampFormats { 253 | if t, err := time.Parse(format, s); err == nil { 254 | return t, true 255 | } 256 | } 257 | return time.Time{}, false 258 | } 259 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/errors.go: -------------------------------------------------------------------------------- 1 | // Package errors provides simple error handling primitives. 2 | // 3 | // The traditional error handling idiom in Go is roughly akin to 4 | // 5 | // if err != nil { 6 | // return err 7 | // } 8 | // 9 | // which when applied recursively up the call stack results in error reports 10 | // without context or debugging information. The errors package allows 11 | // programmers to add context to the failure path in their code in a way 12 | // that does not destroy the original value of the error. 13 | // 14 | // Adding context to an error 15 | // 16 | // The errors.Wrap function returns a new error that adds context to the 17 | // original error by recording a stack trace at the point Wrap is called, 18 | // together with the supplied message. For example 19 | // 20 | // _, err := ioutil.ReadAll(r) 21 | // if err != nil { 22 | // return errors.Wrap(err, "read failed") 23 | // } 24 | // 25 | // If additional control is required, the errors.WithStack and 26 | // errors.WithMessage functions destructure errors.Wrap into its component 27 | // operations: annotating an error with a stack trace and with a message, 28 | // respectively. 29 | // 30 | // Retrieving the cause of an error 31 | // 32 | // Using errors.Wrap constructs a stack of errors, adding context to the 33 | // preceding error. Depending on the nature of the error it may be necessary 34 | // to reverse the operation of errors.Wrap to retrieve the original error 35 | // for inspection. Any error value which implements this interface 36 | // 37 | // type causer interface { 38 | // Cause() error 39 | // } 40 | // 41 | // can be inspected by errors.Cause. errors.Cause will recursively retrieve 42 | // the topmost error that does not implement causer, which is assumed to be 43 | // the original cause. For example: 44 | // 45 | // switch err := errors.Cause(err).(type) { 46 | // case *MyError: 47 | // // handle specifically 48 | // default: 49 | // // unknown error 50 | // } 51 | // 52 | // Although the causer interface is not exported by this package, it is 53 | // considered a part of its stable public interface. 54 | // 55 | // Formatted printing of errors 56 | // 57 | // All error values returned from this package implement fmt.Formatter and can 58 | // be formatted by the fmt package. The following verbs are supported: 59 | // 60 | // %s print the error. If the error has a Cause it will be 61 | // printed recursively. 62 | // %v see %s 63 | // %+v extended format. Each Frame of the error's StackTrace will 64 | // be printed in detail. 65 | // 66 | // Retrieving the stack trace of an error or wrapper 67 | // 68 | // New, Errorf, Wrap, and Wrapf record a stack trace at the point they are 69 | // invoked. This information can be retrieved with the following interface: 70 | // 71 | // type stackTracer interface { 72 | // StackTrace() errors.StackTrace 73 | // } 74 | // 75 | // The returned errors.StackTrace type is defined as 76 | // 77 | // type StackTrace []Frame 78 | // 79 | // The Frame type represents a call site in the stack trace. Frame supports 80 | // the fmt.Formatter interface that can be used for printing information about 81 | // the stack trace of this error. For example: 82 | // 83 | // if err, ok := err.(stackTracer); ok { 84 | // for _, f := range err.StackTrace() { 85 | // fmt.Printf("%+s:%d", f) 86 | // } 87 | // } 88 | // 89 | // Although the stackTracer interface is not exported by this package, it is 90 | // considered a part of its stable public interface. 91 | // 92 | // See the documentation for Frame.Format for more details. 93 | package errors 94 | 95 | import ( 96 | "fmt" 97 | "io" 98 | ) 99 | 100 | // New returns an error with the supplied message. 101 | // New also records the stack trace at the point it was called. 102 | func New(message string) error { 103 | return &fundamental{ 104 | msg: message, 105 | stack: callers(), 106 | } 107 | } 108 | 109 | // Errorf formats according to a format specifier and returns the string 110 | // as a value that satisfies error. 111 | // Errorf also records the stack trace at the point it was called. 112 | func Errorf(format string, args ...interface{}) error { 113 | return &fundamental{ 114 | msg: fmt.Sprintf(format, args...), 115 | stack: callers(), 116 | } 117 | } 118 | 119 | // fundamental is an error that has a message and a stack, but no caller. 120 | type fundamental struct { 121 | msg string 122 | *stack 123 | } 124 | 125 | func (f *fundamental) Error() string { return f.msg } 126 | 127 | func (f *fundamental) Format(s fmt.State, verb rune) { 128 | switch verb { 129 | case 'v': 130 | if s.Flag('+') { 131 | io.WriteString(s, f.msg) 132 | f.stack.Format(s, verb) 133 | return 134 | } 135 | fallthrough 136 | case 's': 137 | io.WriteString(s, f.msg) 138 | case 'q': 139 | fmt.Fprintf(s, "%q", f.msg) 140 | } 141 | } 142 | 143 | // WithStack annotates err with a stack trace at the point WithStack was called. 144 | // If err is nil, WithStack returns nil. 145 | func WithStack(err error) error { 146 | if err == nil { 147 | return nil 148 | } 149 | return &withStack{ 150 | err, 151 | callers(), 152 | } 153 | } 154 | 155 | type withStack struct { 156 | error 157 | *stack 158 | } 159 | 160 | func (w *withStack) Cause() error { return w.error } 161 | 162 | func (w *withStack) Format(s fmt.State, verb rune) { 163 | switch verb { 164 | case 'v': 165 | if s.Flag('+') { 166 | fmt.Fprintf(s, "%+v", w.Cause()) 167 | w.stack.Format(s, verb) 168 | return 169 | } 170 | fallthrough 171 | case 's': 172 | io.WriteString(s, w.Error()) 173 | case 'q': 174 | fmt.Fprintf(s, "%q", w.Error()) 175 | } 176 | } 177 | 178 | // Wrap returns an error annotating err with a stack trace 179 | // at the point Wrap is called, and the supplied message. 180 | // If err is nil, Wrap returns nil. 181 | func Wrap(err error, message string) error { 182 | if err == nil { 183 | return nil 184 | } 185 | err = &withMessage{ 186 | cause: err, 187 | msg: message, 188 | } 189 | return &withStack{ 190 | err, 191 | callers(), 192 | } 193 | } 194 | 195 | // Wrapf returns an error annotating err with a stack trace 196 | // at the point Wrapf is called, and the format specifier. 197 | // If err is nil, Wrapf returns nil. 198 | func Wrapf(err error, format string, args ...interface{}) error { 199 | if err == nil { 200 | return nil 201 | } 202 | err = &withMessage{ 203 | cause: err, 204 | msg: fmt.Sprintf(format, args...), 205 | } 206 | return &withStack{ 207 | err, 208 | callers(), 209 | } 210 | } 211 | 212 | // WithMessage annotates err with a new message. 213 | // If err is nil, WithMessage returns nil. 214 | func WithMessage(err error, message string) error { 215 | if err == nil { 216 | return nil 217 | } 218 | return &withMessage{ 219 | cause: err, 220 | msg: message, 221 | } 222 | } 223 | 224 | // WithMessagef annotates err with the format specifier. 225 | // If err is nil, WithMessagef returns nil. 226 | func WithMessagef(err error, format string, args ...interface{}) error { 227 | if err == nil { 228 | return nil 229 | } 230 | return &withMessage{ 231 | cause: err, 232 | msg: fmt.Sprintf(format, args...), 233 | } 234 | } 235 | 236 | type withMessage struct { 237 | cause error 238 | msg string 239 | } 240 | 241 | func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() } 242 | func (w *withMessage) Cause() error { return w.cause } 243 | 244 | func (w *withMessage) Format(s fmt.State, verb rune) { 245 | switch verb { 246 | case 'v': 247 | if s.Flag('+') { 248 | fmt.Fprintf(s, "%+v\n", w.Cause()) 249 | io.WriteString(s, w.msg) 250 | return 251 | } 252 | fallthrough 253 | case 's', 'q': 254 | io.WriteString(s, w.Error()) 255 | } 256 | } 257 | 258 | // Cause returns the underlying cause of the error, if possible. 259 | // An error value has a cause if it implements the following 260 | // interface: 261 | // 262 | // type causer interface { 263 | // Cause() error 264 | // } 265 | // 266 | // If the error does not implement Cause, the original error will 267 | // be returned. If the error is nil, nil will be returned without further 268 | // investigation. 269 | func Cause(err error) error { 270 | type causer interface { 271 | Cause() error 272 | } 273 | 274 | for err != nil { 275 | cause, ok := err.(causer) 276 | if !ok { 277 | break 278 | } 279 | err = cause.Cause() 280 | } 281 | return err 282 | } 283 | -------------------------------------------------------------------------------- /vendor/github.com/imdario/mergo/merge.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Dario Castañé. All rights reserved. 2 | // Copyright 2009 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // Based on src/pkg/reflect/deepequal.go from official 7 | // golang's stdlib. 8 | 9 | package mergo 10 | 11 | import ( 12 | "fmt" 13 | "reflect" 14 | ) 15 | 16 | func hasExportedField(dst reflect.Value) (exported bool) { 17 | for i, n := 0, dst.NumField(); i < n; i++ { 18 | field := dst.Type().Field(i) 19 | if field.Anonymous && dst.Field(i).Kind() == reflect.Struct { 20 | exported = exported || hasExportedField(dst.Field(i)) 21 | } else { 22 | exported = exported || len(field.PkgPath) == 0 23 | } 24 | } 25 | return 26 | } 27 | 28 | type Config struct { 29 | Overwrite bool 30 | AppendSlice bool 31 | Transformers Transformers 32 | overwriteWithEmptyValue bool 33 | } 34 | 35 | type Transformers interface { 36 | Transformer(reflect.Type) func(dst, src reflect.Value) error 37 | } 38 | 39 | // Traverses recursively both values, assigning src's fields values to dst. 40 | // The map argument tracks comparisons that have already been seen, which allows 41 | // short circuiting on recursive types. 42 | func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) { 43 | overwrite := config.Overwrite 44 | overwriteWithEmptySrc := config.overwriteWithEmptyValue 45 | config.overwriteWithEmptyValue = false 46 | 47 | if !src.IsValid() { 48 | return 49 | } 50 | if dst.CanAddr() { 51 | addr := dst.UnsafeAddr() 52 | h := 17 * addr 53 | seen := visited[h] 54 | typ := dst.Type() 55 | for p := seen; p != nil; p = p.next { 56 | if p.ptr == addr && p.typ == typ { 57 | return nil 58 | } 59 | } 60 | // Remember, remember... 61 | visited[h] = &visit{addr, typ, seen} 62 | } 63 | 64 | if config.Transformers != nil && !isEmptyValue(dst) { 65 | if fn := config.Transformers.Transformer(dst.Type()); fn != nil { 66 | err = fn(dst, src) 67 | return 68 | } 69 | } 70 | 71 | switch dst.Kind() { 72 | case reflect.Struct: 73 | if hasExportedField(dst) { 74 | for i, n := 0, dst.NumField(); i < n; i++ { 75 | if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, config); err != nil { 76 | return 77 | } 78 | } 79 | } else { 80 | if dst.CanSet() && (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) { 81 | dst.Set(src) 82 | } 83 | } 84 | case reflect.Map: 85 | if dst.IsNil() && !src.IsNil() { 86 | dst.Set(reflect.MakeMap(dst.Type())) 87 | } 88 | for _, key := range src.MapKeys() { 89 | srcElement := src.MapIndex(key) 90 | if !srcElement.IsValid() { 91 | continue 92 | } 93 | dstElement := dst.MapIndex(key) 94 | switch srcElement.Kind() { 95 | case reflect.Chan, reflect.Func, reflect.Map, reflect.Interface, reflect.Slice: 96 | if srcElement.IsNil() { 97 | continue 98 | } 99 | fallthrough 100 | default: 101 | if !srcElement.CanInterface() { 102 | continue 103 | } 104 | switch reflect.TypeOf(srcElement.Interface()).Kind() { 105 | case reflect.Struct: 106 | fallthrough 107 | case reflect.Ptr: 108 | fallthrough 109 | case reflect.Map: 110 | srcMapElm := srcElement 111 | dstMapElm := dstElement 112 | if srcMapElm.CanInterface() { 113 | srcMapElm = reflect.ValueOf(srcMapElm.Interface()) 114 | if dstMapElm.IsValid() { 115 | dstMapElm = reflect.ValueOf(dstMapElm.Interface()) 116 | } 117 | } 118 | if err = deepMerge(dstMapElm, srcMapElm, visited, depth+1, config); err != nil { 119 | return 120 | } 121 | case reflect.Slice: 122 | srcSlice := reflect.ValueOf(srcElement.Interface()) 123 | 124 | var dstSlice reflect.Value 125 | if !dstElement.IsValid() || dstElement.IsNil() { 126 | dstSlice = reflect.MakeSlice(srcSlice.Type(), 0, srcSlice.Len()) 127 | } else { 128 | dstSlice = reflect.ValueOf(dstElement.Interface()) 129 | } 130 | 131 | if (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { 132 | dstSlice = srcSlice 133 | } else if config.AppendSlice { 134 | if srcSlice.Type() != dstSlice.Type() { 135 | return fmt.Errorf("cannot append two slice with different type (%s, %s)", srcSlice.Type(), dstSlice.Type()) 136 | } 137 | dstSlice = reflect.AppendSlice(dstSlice, srcSlice) 138 | } 139 | dst.SetMapIndex(key, dstSlice) 140 | } 141 | } 142 | if dstElement.IsValid() && !isEmptyValue(dstElement) && (reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map || reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice) { 143 | continue 144 | } 145 | 146 | if srcElement.IsValid() && (overwrite || (!dstElement.IsValid() || isEmptyValue(dstElement))) { 147 | if dst.IsNil() { 148 | dst.Set(reflect.MakeMap(dst.Type())) 149 | } 150 | dst.SetMapIndex(key, srcElement) 151 | } 152 | } 153 | case reflect.Slice: 154 | if !dst.CanSet() { 155 | break 156 | } 157 | if (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { 158 | dst.Set(src) 159 | } else if config.AppendSlice { 160 | if src.Type() != dst.Type() { 161 | return fmt.Errorf("cannot append two slice with different type (%s, %s)", src.Type(), dst.Type()) 162 | } 163 | dst.Set(reflect.AppendSlice(dst, src)) 164 | } 165 | case reflect.Ptr: 166 | fallthrough 167 | case reflect.Interface: 168 | if src.IsNil() { 169 | break 170 | } 171 | if src.Kind() != reflect.Interface { 172 | if dst.IsNil() || overwrite { 173 | if dst.CanSet() && (overwrite || isEmptyValue(dst)) { 174 | dst.Set(src) 175 | } 176 | } else if src.Kind() == reflect.Ptr { 177 | if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { 178 | return 179 | } 180 | } else if dst.Elem().Type() == src.Type() { 181 | if err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil { 182 | return 183 | } 184 | } else { 185 | return ErrDifferentArgumentsTypes 186 | } 187 | break 188 | } 189 | if dst.IsNil() || overwrite { 190 | if dst.CanSet() && (overwrite || isEmptyValue(dst)) { 191 | dst.Set(src) 192 | } 193 | } else if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { 194 | return 195 | } 196 | default: 197 | if dst.CanSet() && (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) { 198 | dst.Set(src) 199 | } 200 | } 201 | return 202 | } 203 | 204 | // Merge will fill any empty for value type attributes on the dst struct using corresponding 205 | // src attributes if they themselves are not empty. dst and src must be valid same-type structs 206 | // and dst must be a pointer to struct. 207 | // It won't merge unexported (private) fields and will do recursively any exported field. 208 | func Merge(dst, src interface{}, opts ...func(*Config)) error { 209 | return merge(dst, src, opts...) 210 | } 211 | 212 | // MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overriden by 213 | // non-empty src attribute values. 214 | // Deprecated: use Merge(…) with WithOverride 215 | func MergeWithOverwrite(dst, src interface{}, opts ...func(*Config)) error { 216 | return merge(dst, src, append(opts, WithOverride)...) 217 | } 218 | 219 | // WithTransformers adds transformers to merge, allowing to customize the merging of some types. 220 | func WithTransformers(transformers Transformers) func(*Config) { 221 | return func(config *Config) { 222 | config.Transformers = transformers 223 | } 224 | } 225 | 226 | // WithOverride will make merge override non-empty dst attributes with non-empty src attributes values. 227 | func WithOverride(config *Config) { 228 | config.Overwrite = true 229 | } 230 | 231 | // WithAppendSlice will make merge append slices instead of overwriting it 232 | func WithAppendSlice(config *Config) { 233 | config.AppendSlice = true 234 | } 235 | 236 | func merge(dst, src interface{}, opts ...func(*Config)) error { 237 | var ( 238 | vDst, vSrc reflect.Value 239 | err error 240 | ) 241 | 242 | config := &Config{} 243 | 244 | for _, opt := range opts { 245 | opt(config) 246 | } 247 | 248 | if vDst, vSrc, err = resolveValues(dst, src); err != nil { 249 | return err 250 | } 251 | if vDst.Type() != vSrc.Type() { 252 | return ErrDifferentArgumentsTypes 253 | } 254 | return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config) 255 | } 256 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2016 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | Package spew implements a deep pretty printer for Go data structures to aid in 19 | debugging. 20 | 21 | A quick overview of the additional features spew provides over the built-in 22 | printing facilities for Go data types are as follows: 23 | 24 | * Pointers are dereferenced and followed 25 | * Circular data structures are detected and handled properly 26 | * Custom Stringer/error interfaces are optionally invoked, including 27 | on unexported types 28 | * Custom types which only implement the Stringer/error interfaces via 29 | a pointer receiver are optionally invoked when passing non-pointer 30 | variables 31 | * Byte arrays and slices are dumped like the hexdump -C command which 32 | includes offsets, byte values in hex, and ASCII output (only when using 33 | Dump style) 34 | 35 | There are two different approaches spew allows for dumping Go data structures: 36 | 37 | * Dump style which prints with newlines, customizable indentation, 38 | and additional debug information such as types and all pointer addresses 39 | used to indirect to the final value 40 | * A custom Formatter interface that integrates cleanly with the standard fmt 41 | package and replaces %v, %+v, %#v, and %#+v to provide inline printing 42 | similar to the default %v while providing the additional functionality 43 | outlined above and passing unsupported format verbs such as %x and %q 44 | along to fmt 45 | 46 | Quick Start 47 | 48 | This section demonstrates how to quickly get started with spew. See the 49 | sections below for further details on formatting and configuration options. 50 | 51 | To dump a variable with full newlines, indentation, type, and pointer 52 | information use Dump, Fdump, or Sdump: 53 | spew.Dump(myVar1, myVar2, ...) 54 | spew.Fdump(someWriter, myVar1, myVar2, ...) 55 | str := spew.Sdump(myVar1, myVar2, ...) 56 | 57 | Alternatively, if you would prefer to use format strings with a compacted inline 58 | printing style, use the convenience wrappers Printf, Fprintf, etc with 59 | %v (most compact), %+v (adds pointer addresses), %#v (adds types), or 60 | %#+v (adds types and pointer addresses): 61 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 62 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 63 | spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 64 | spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 65 | 66 | Configuration Options 67 | 68 | Configuration of spew is handled by fields in the ConfigState type. For 69 | convenience, all of the top-level functions use a global state available 70 | via the spew.Config global. 71 | 72 | It is also possible to create a ConfigState instance that provides methods 73 | equivalent to the top-level functions. This allows concurrent configuration 74 | options. See the ConfigState documentation for more details. 75 | 76 | The following configuration options are available: 77 | * Indent 78 | String to use for each indentation level for Dump functions. 79 | It is a single space by default. A popular alternative is "\t". 80 | 81 | * MaxDepth 82 | Maximum number of levels to descend into nested data structures. 83 | There is no limit by default. 84 | 85 | * DisableMethods 86 | Disables invocation of error and Stringer interface methods. 87 | Method invocation is enabled by default. 88 | 89 | * DisablePointerMethods 90 | Disables invocation of error and Stringer interface methods on types 91 | which only accept pointer receivers from non-pointer variables. 92 | Pointer method invocation is enabled by default. 93 | 94 | * DisablePointerAddresses 95 | DisablePointerAddresses specifies whether to disable the printing of 96 | pointer addresses. This is useful when diffing data structures in tests. 97 | 98 | * DisableCapacities 99 | DisableCapacities specifies whether to disable the printing of 100 | capacities for arrays, slices, maps and channels. This is useful when 101 | diffing data structures in tests. 102 | 103 | * ContinueOnMethod 104 | Enables recursion into types after invoking error and Stringer interface 105 | methods. Recursion after method invocation is disabled by default. 106 | 107 | * SortKeys 108 | Specifies map keys should be sorted before being printed. Use 109 | this to have a more deterministic, diffable output. Note that 110 | only native types (bool, int, uint, floats, uintptr and string) 111 | and types which implement error or Stringer interfaces are 112 | supported with other types sorted according to the 113 | reflect.Value.String() output which guarantees display 114 | stability. Natural map order is used by default. 115 | 116 | * SpewKeys 117 | Specifies that, as a last resort attempt, map keys should be 118 | spewed to strings and sorted by those strings. This is only 119 | considered if SortKeys is true. 120 | 121 | Dump Usage 122 | 123 | Simply call spew.Dump with a list of variables you want to dump: 124 | 125 | spew.Dump(myVar1, myVar2, ...) 126 | 127 | You may also call spew.Fdump if you would prefer to output to an arbitrary 128 | io.Writer. For example, to dump to standard error: 129 | 130 | spew.Fdump(os.Stderr, myVar1, myVar2, ...) 131 | 132 | A third option is to call spew.Sdump to get the formatted output as a string: 133 | 134 | str := spew.Sdump(myVar1, myVar2, ...) 135 | 136 | Sample Dump Output 137 | 138 | See the Dump example for details on the setup of the types and variables being 139 | shown here. 140 | 141 | (main.Foo) { 142 | unexportedField: (*main.Bar)(0xf84002e210)({ 143 | flag: (main.Flag) flagTwo, 144 | data: (uintptr) 145 | }), 146 | ExportedField: (map[interface {}]interface {}) (len=1) { 147 | (string) (len=3) "one": (bool) true 148 | } 149 | } 150 | 151 | Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C 152 | command as shown. 153 | ([]uint8) (len=32 cap=32) { 154 | 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | 155 | 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| 156 | 00000020 31 32 |12| 157 | } 158 | 159 | Custom Formatter 160 | 161 | Spew provides a custom formatter that implements the fmt.Formatter interface 162 | so that it integrates cleanly with standard fmt package printing functions. The 163 | formatter is useful for inline printing of smaller data types similar to the 164 | standard %v format specifier. 165 | 166 | The custom formatter only responds to the %v (most compact), %+v (adds pointer 167 | addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb 168 | combinations. Any other verbs such as %x and %q will be sent to the the 169 | standard fmt package for formatting. In addition, the custom formatter ignores 170 | the width and precision arguments (however they will still work on the format 171 | specifiers not handled by the custom formatter). 172 | 173 | Custom Formatter Usage 174 | 175 | The simplest way to make use of the spew custom formatter is to call one of the 176 | convenience functions such as spew.Printf, spew.Println, or spew.Printf. The 177 | functions have syntax you are most likely already familiar with: 178 | 179 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 180 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 181 | spew.Println(myVar, myVar2) 182 | spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 183 | spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 184 | 185 | See the Index for the full list convenience functions. 186 | 187 | Sample Formatter Output 188 | 189 | Double pointer to a uint8: 190 | %v: <**>5 191 | %+v: <**>(0xf8400420d0->0xf8400420c8)5 192 | %#v: (**uint8)5 193 | %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 194 | 195 | Pointer to circular struct with a uint8 field and a pointer to itself: 196 | %v: <*>{1 <*>} 197 | %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} 198 | %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} 199 | %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} 200 | 201 | See the Printf example for details on the setup of variables being shown 202 | here. 203 | 204 | Errors 205 | 206 | Since it is possible for custom Stringer/error interfaces to panic, spew 207 | detects them and handles them internally by printing the panic information 208 | inline with the output. Since spew is intended to provide deep pretty printing 209 | capabilities on structures, it intentionally does not return any errors. 210 | */ 211 | package spew 212 | --------------------------------------------------------------------------------