summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/spf13/cast
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/spf13/cast')
-rw-r--r--vendor/github.com/spf13/cast/.gitignore25
-rw-r--r--vendor/github.com/spf13/cast/.travis.yml14
-rw-r--r--vendor/github.com/spf13/cast/LICENSE21
-rw-r--r--vendor/github.com/spf13/cast/Makefile38
-rw-r--r--vendor/github.com/spf13/cast/README.md75
-rw-r--r--vendor/github.com/spf13/cast/cast.go153
-rw-r--r--vendor/github.com/spf13/cast/cast_test.go1151
-rw-r--r--vendor/github.com/spf13/cast/caste.go1117
8 files changed, 2594 insertions, 0 deletions
diff --git a/vendor/github.com/spf13/cast/.gitignore b/vendor/github.com/spf13/cast/.gitignore
new file mode 100644
index 000000000..53053a8ac
--- /dev/null
+++ b/vendor/github.com/spf13/cast/.gitignore
@@ -0,0 +1,25 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+
+*.bench
diff --git a/vendor/github.com/spf13/cast/.travis.yml b/vendor/github.com/spf13/cast/.travis.yml
new file mode 100644
index 000000000..4da976684
--- /dev/null
+++ b/vendor/github.com/spf13/cast/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+sudo: required
+go:
+ - 1.7.5
+ - 1.8
+ - tip
+os:
+ - linux
+matrix:
+ allow_failures:
+ - go: tip
+ fast_finish: true
+script:
+ - make check
diff --git a/vendor/github.com/spf13/cast/LICENSE b/vendor/github.com/spf13/cast/LICENSE
new file mode 100644
index 000000000..4527efb9c
--- /dev/null
+++ b/vendor/github.com/spf13/cast/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Steve Francia
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE. \ No newline at end of file
diff --git a/vendor/github.com/spf13/cast/Makefile b/vendor/github.com/spf13/cast/Makefile
new file mode 100644
index 000000000..7ccf8930b
--- /dev/null
+++ b/vendor/github.com/spf13/cast/Makefile
@@ -0,0 +1,38 @@
+# A Self-Documenting Makefile: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
+
+.PHONY: check fmt lint test test-race vet test-cover-html help
+.DEFAULT_GOAL := help
+
+check: test-race fmt vet lint ## Run tests and linters
+
+test: ## Run tests
+ go test ./...
+
+test-race: ## Run tests with race detector
+ go test -race ./...
+
+fmt: ## Run gofmt linter
+ @for d in `go list` ; do \
+ if [ "`gofmt -l -s $$GOPATH/src/$$d | tee /dev/stderr`" ]; then \
+ echo "^ improperly formatted go files" && echo && exit 1; \
+ fi \
+ done
+
+lint: ## Run golint linter
+ @for d in `go list` ; do \
+ if [ "`golint $$d | tee /dev/stderr`" ]; then \
+ echo "^ golint errors!" && echo && exit 1; \
+ fi \
+ done
+
+vet: ## Run go vet linter
+ @if [ "`go vet | tee /dev/stderr`" ]; then \
+ echo "^ go vet errors!" && echo && exit 1; \
+ fi
+
+test-cover-html: ## Generate test coverage report
+ go test -coverprofile=coverage.out -covermode=count
+ go tool cover -func=coverage.out
+
+help:
+ @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
diff --git a/vendor/github.com/spf13/cast/README.md b/vendor/github.com/spf13/cast/README.md
new file mode 100644
index 000000000..e6939397d
--- /dev/null
+++ b/vendor/github.com/spf13/cast/README.md
@@ -0,0 +1,75 @@
+cast
+====
+[![GoDoc](https://godoc.org/github.com/spf13/cast?status.svg)](https://godoc.org/github.com/spf13/cast)
+[![Build Status](https://api.travis-ci.org/spf13/cast.svg?branch=master)](https://travis-ci.org/spf13/cast)
+[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cast)](https://goreportcard.com/report/github.com/spf13/cast)
+
+Easy and safe casting from one type to another in Go
+
+Don’t Panic! ... Cast
+
+## What is Cast?
+
+Cast is a library to convert between different go types in a consistent and easy way.
+
+Cast provides simple functions to easily convert a number to a string, an
+interface into a bool, etc. Cast does this intelligently when an obvious
+conversion is possible. It doesn’t make any attempts to guess what you meant,
+for example you can only convert a string to an int when it is a string
+representation of an int such as “8”. Cast was developed for use in
+[Hugo](http://hugo.spf13.com), a website engine which uses YAML, TOML or JSON
+for meta data.
+
+## Why use Cast?
+
+When working with dynamic data in Go you often need to cast or convert the data
+from one type into another. Cast goes beyond just using type assertion (though
+it uses that when possible) to provide a very straightforward and convenient
+library.
+
+If you are working with interfaces to handle things like dynamic content
+you’ll need an easy way to convert an interface into a given type. This
+is the library for you.
+
+If you are taking in data from YAML, TOML or JSON or other formats which lack
+full types, then Cast is the library for you.
+
+## Usage
+
+Cast provides a handful of To_____ methods. These methods will always return
+the desired type. **If input is provided that will not convert to that type, the
+0 or nil value for that type will be returned**.
+
+Cast also provides identical methods To_____E. These return the same result as
+the To_____ methods, plus an additional error which tells you if it successfully
+converted. Using these methods you can tell the difference between when the
+input matched the zero value or when the conversion failed and the zero value
+was returned.
+
+The following examples are merely a sample of what is available. Please review
+the code for a complete set.
+
+### Example ‘ToString’:
+
+ cast.ToString("mayonegg") // "mayonegg"
+ cast.ToString(8) // "8"
+ cast.ToString(8.31) // "8.31"
+ cast.ToString([]byte("one time")) // "one time"
+ cast.ToString(nil) // ""
+
+ var foo interface{} = "one more time"
+ cast.ToString(foo) // "one more time"
+
+
+### Example ‘ToInt’:
+
+ cast.ToInt(8) // 8
+ cast.ToInt(8.31) // 8
+ cast.ToInt("8") // 8
+ cast.ToInt(true) // 1
+ cast.ToInt(false) // 0
+
+ var eight interface{} = 8
+ cast.ToInt(eight) // 8
+ cast.ToInt(nil) // 0
+
diff --git a/vendor/github.com/spf13/cast/cast.go b/vendor/github.com/spf13/cast/cast.go
new file mode 100644
index 000000000..dc504b432
--- /dev/null
+++ b/vendor/github.com/spf13/cast/cast.go
@@ -0,0 +1,153 @@
+// Copyright © 2014 Steve Francia <spf@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// Package cast provides easy and safe casting in Go.
+package cast
+
+import "time"
+
+// ToBool casts an interface to a bool type.
+func ToBool(i interface{}) bool {
+ v, _ := ToBoolE(i)
+ return v
+}
+
+// ToTime casts an interface to a time.Time type.
+func ToTime(i interface{}) time.Time {
+ v, _ := ToTimeE(i)
+ return v
+}
+
+// ToDuration casts an interface to a time.Duration type.
+func ToDuration(i interface{}) time.Duration {
+ v, _ := ToDurationE(i)
+ return v
+}
+
+// ToFloat64 casts an interface to a float64 type.
+func ToFloat64(i interface{}) float64 {
+ v, _ := ToFloat64E(i)
+ return v
+}
+
+// ToFloat32 casts an interface to a float32 type.
+func ToFloat32(i interface{}) float32 {
+ v, _ := ToFloat32E(i)
+ return v
+}
+
+// ToInt64 casts an interface to an int64 type.
+func ToInt64(i interface{}) int64 {
+ v, _ := ToInt64E(i)
+ return v
+}
+
+// ToInt32 casts an interface to an int32 type.
+func ToInt32(i interface{}) int32 {
+ v, _ := ToInt32E(i)
+ return v
+}
+
+// ToInt16 casts an interface to an int16 type.
+func ToInt16(i interface{}) int16 {
+ v, _ := ToInt16E(i)
+ return v
+}
+
+// ToInt8 casts an interface to an int8 type.
+func ToInt8(i interface{}) int8 {
+ v, _ := ToInt8E(i)
+ return v
+}
+
+// ToInt casts an interface to an int type.
+func ToInt(i interface{}) int {
+ v, _ := ToIntE(i)
+ return v
+}
+
+// ToUint casts an interface to a uint type.
+func ToUint(i interface{}) uint {
+ v, _ := ToUintE(i)
+ return v
+}
+
+// ToUint64 casts an interface to a uint64 type.
+func ToUint64(i interface{}) uint64 {
+ v, _ := ToUint64E(i)
+ return v
+}
+
+// ToUint32 casts an interface to a uint32 type.
+func ToUint32(i interface{}) uint32 {
+ v, _ := ToUint32E(i)
+ return v
+}
+
+// ToUint16 casts an interface to a uint16 type.
+func ToUint16(i interface{}) uint16 {
+ v, _ := ToUint16E(i)
+ return v
+}
+
+// ToUint8 casts an interface to a uint8 type.
+func ToUint8(i interface{}) uint8 {
+ v, _ := ToUint8E(i)
+ return v
+}
+
+// ToString casts an interface to a string type.
+func ToString(i interface{}) string {
+ v, _ := ToStringE(i)
+ return v
+}
+
+// ToStringMapString casts an interface to a map[string]string type.
+func ToStringMapString(i interface{}) map[string]string {
+ v, _ := ToStringMapStringE(i)
+ return v
+}
+
+// ToStringMapStringSlice casts an interface to a map[string][]string type.
+func ToStringMapStringSlice(i interface{}) map[string][]string {
+ v, _ := ToStringMapStringSliceE(i)
+ return v
+}
+
+// ToStringMapBool casts an interface to a map[string]bool type.
+func ToStringMapBool(i interface{}) map[string]bool {
+ v, _ := ToStringMapBoolE(i)
+ return v
+}
+
+// ToStringMap casts an interface to a map[string]interface{} type.
+func ToStringMap(i interface{}) map[string]interface{} {
+ v, _ := ToStringMapE(i)
+ return v
+}
+
+// ToSlice casts an interface to a []interface{} type.
+func ToSlice(i interface{}) []interface{} {
+ v, _ := ToSliceE(i)
+ return v
+}
+
+// ToBoolSlice casts an interface to a []bool type.
+func ToBoolSlice(i interface{}) []bool {
+ v, _ := ToBoolSliceE(i)
+ return v
+}
+
+// ToStringSlice casts an interface to a []string type.
+func ToStringSlice(i interface{}) []string {
+ v, _ := ToStringSliceE(i)
+ return v
+}
+
+// ToIntSlice casts an interface to a []int type.
+func ToIntSlice(i interface{}) []int {
+ v, _ := ToIntSliceE(i)
+ return v
+}
diff --git a/vendor/github.com/spf13/cast/cast_test.go b/vendor/github.com/spf13/cast/cast_test.go
new file mode 100644
index 000000000..2bb8c5f54
--- /dev/null
+++ b/vendor/github.com/spf13/cast/cast_test.go
@@ -0,0 +1,1151 @@
+// Copyright © 2014 Steve Francia <spf@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "fmt"
+ "html/template"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestToUintE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect uint
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {int(-8), 0, true},
+ {int8(-8), 0, true},
+ {int16(-8), 0, true},
+ {int32(-8), 0, true},
+ {int64(-8), 0, true},
+ {float32(-8.31), 0, true},
+ {float64(-8.31), 0, true},
+ {"-8", 0, true},
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToUintE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test:
+ v = ToUint(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToUint64E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect uint64
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {int(-8), 0, true},
+ {int8(-8), 0, true},
+ {int16(-8), 0, true},
+ {int32(-8), 0, true},
+ {int64(-8), 0, true},
+ {float32(-8.31), 0, true},
+ {float64(-8.31), 0, true},
+ {"-8", 0, true},
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToUint64E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test:
+ v = ToUint64(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToUint32E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect uint32
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ {int(-8), 0, true},
+ {int8(-8), 0, true},
+ {int16(-8), 0, true},
+ {int32(-8), 0, true},
+ {int64(-8), 0, true},
+ {float32(-8.31), 0, true},
+ {float64(-8.31), 0, true},
+ {"-8", 0, true},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToUint32E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test:
+ v = ToUint32(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToUint16E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect uint16
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {int(-8), 0, true},
+ {int8(-8), 0, true},
+ {int16(-8), 0, true},
+ {int32(-8), 0, true},
+ {int64(-8), 0, true},
+ {float32(-8.31), 0, true},
+ {float64(-8.31), 0, true},
+ {"-8", 0, true},
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToUint16E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToUint16(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToUint8E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect uint8
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {int(-8), 0, true},
+ {int8(-8), 0, true},
+ {int16(-8), 0, true},
+ {int32(-8), 0, true},
+ {int64(-8), 0, true},
+ {float32(-8.31), 0, true},
+ {float64(-8.31), 0, true},
+ {"-8", 0, true},
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToUint8E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToUint8(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToIntE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect int
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToIntE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToInt(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToInt64E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect int64
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToInt64E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToInt64(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToInt32E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect int32
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToInt32E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToInt32(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToInt16E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect int16
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToInt16E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToInt16(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToInt8E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect int8
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8, false},
+ {float64(8.31), 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ {"8", 8, false},
+ {nil, 0, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToInt8E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToInt8(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToFloat64E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect float64
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8), 8, false},
+ {float64(8.31), 8.31, false},
+ {"8", 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToFloat64E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToFloat64(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToFloat32E(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect float32
+ iserr bool
+ }{
+ {int(8), 8, false},
+ {int8(8), 8, false},
+ {int16(8), 8, false},
+ {int32(8), 8, false},
+ {int64(8), 8, false},
+ {uint(8), 8, false},
+ {uint8(8), 8, false},
+ {uint16(8), 8, false},
+ {uint32(8), 8, false},
+ {uint64(8), 8, false},
+ {float32(8.31), 8.31, false},
+ {float64(8.31), 8.31, false},
+ {"8", 8, false},
+ {true, 1, false},
+ {false, 0, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToFloat32E(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToFloat32(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToStringE(t *testing.T) {
+ type Key struct {
+ k string
+ }
+ key := &Key{"foo"}
+
+ tests := []struct {
+ input interface{}
+ expect string
+ iserr bool
+ }{
+ {int(8), "8", false},
+ {int8(8), "8", false},
+ {int16(8), "8", false},
+ {int32(8), "8", false},
+ {int64(8), "8", false},
+ {uint(8), "8", false},
+ {uint8(8), "8", false},
+ {uint16(8), "8", false},
+ {uint32(8), "8", false},
+ {uint64(8), "8", false},
+ {float32(8.31), "8.31", false},
+ {float64(8.31), "8.31", false},
+ {true, "true", false},
+ {false, "false", false},
+ {nil, "", false},
+ {[]byte("one time"), "one time", false},
+ {"one more time", "one more time", false},
+ {template.HTML("one time"), "one time", false},
+ {template.URL("http://somehost.foo"), "http://somehost.foo", false},
+ {template.JS("(1+2)"), "(1+2)", false},
+ {template.CSS("a"), "a", false},
+ {template.HTMLAttr("a"), "a", false},
+ // errors
+ {testing.T{}, "", true},
+ {key, "", true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToStringE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToString(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+type foo struct {
+ val string
+}
+
+func (x foo) String() string {
+ return x.val
+}
+
+func TestStringerToString(t *testing.T) {
+ var x foo
+ x.val = "bar"
+ assert.Equal(t, "bar", ToString(x))
+}
+
+type fu struct {
+ val string
+}
+
+func (x fu) Error() string {
+ return x.val
+}
+
+func TestErrorToString(t *testing.T) {
+ var x fu
+ x.val = "bar"
+ assert.Equal(t, "bar", ToString(x))
+}
+
+func TestStringMapStringSliceE(t *testing.T) {
+ // ToStringMapString inputs/outputs
+ var stringMapString = map[string]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+ var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+ var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+ var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+
+ // ToStringMapStringSlice inputs/outputs
+ var stringMapStringSlice = map[string][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
+ var stringMapInterfaceSlice = map[string][]interface{}{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
+ var stringMapInterfaceInterfaceSlice = map[string]interface{}{"key 1": []interface{}{"value 1", "value 2", "value 3"}, "key 2": []interface{}{"value 1", "value 2", "value 3"}, "key 3": []interface{}{"value 1", "value 2", "value 3"}}
+ var stringMapStringSingleSliceFieldsResult = map[string][]string{"key 1": {"value", "1"}, "key 2": {"value", "2"}, "key 3": {"value", "3"}}
+ var interfaceMapStringSlice = map[interface{}][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
+ var interfaceMapInterfaceSlice = map[interface{}][]interface{}{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
+
+ var stringMapStringSliceMultiple = map[string][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
+ var stringMapStringSliceSingle = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}, "key 3": {"value 3"}}
+
+ var stringMapInterface1 = map[string]interface{}{"key 1": []string{"value 1"}, "key 2": []string{"value 2"}}
+ var stringMapInterfaceResult1 = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}}
+
+ type Key struct {
+ k string
+ }
+
+ tests := []struct {
+ input interface{}
+ expect map[string][]string
+ iserr bool
+ }{
+ {stringMapStringSlice, stringMapStringSlice, false},
+ {stringMapInterfaceSlice, stringMapStringSlice, false},
+ {stringMapInterfaceInterfaceSlice, stringMapStringSlice, false},
+ {stringMapStringSliceMultiple, stringMapStringSlice, false},
+ {stringMapStringSliceMultiple, stringMapStringSlice, false},
+ {stringMapString, stringMapStringSliceSingle, false},
+ {stringMapInterface, stringMapStringSliceSingle, false},
+ {stringMapInterface1, stringMapInterfaceResult1, false},
+ {interfaceMapStringSlice, stringMapStringSlice, false},
+ {interfaceMapInterfaceSlice, stringMapStringSlice, false},
+ {interfaceMapString, stringMapStringSingleSliceFieldsResult, false},
+ {interfaceMapInterface, stringMapStringSingleSliceFieldsResult, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ {map[interface{}]interface{}{"foo": testing.T{}}, nil, true},
+ {map[interface{}]interface{}{Key{"foo"}: "bar"}, nil, true}, // ToStringE(Key{"foo"}) should fail
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToStringMapStringSliceE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToStringMapStringSlice(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToStringMapE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect map[string]interface{}
+ iserr bool
+ }{
+ {map[interface{}]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
+ {map[string]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToStringMapE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToStringMap(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToStringMapBoolE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect map[string]bool
+ iserr bool
+ }{
+ {map[interface{}]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
+ {map[string]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
+ {map[string]bool{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToStringMapBoolE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToStringMapBool(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToStringMapStringE(t *testing.T) {
+ var stringMapString = map[string]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+ var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+ var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+ var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
+
+ tests := []struct {
+ input interface{}
+ expect map[string]string
+ iserr bool
+ }{
+ {stringMapString, stringMapString, false},
+ {stringMapInterface, stringMapString, false},
+ {interfaceMapString, stringMapString, false},
+ {interfaceMapInterface, stringMapString, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToStringMapStringE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToStringMapString(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToBoolSliceE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect []bool
+ iserr bool
+ }{
+ {[]bool{true, false, true}, []bool{true, false, true}, false},
+ {[]interface{}{true, false, true}, []bool{true, false, true}, false},
+ {[]int{1, 0, 1}, []bool{true, false, true}, false},
+ {[]string{"true", "false", "true"}, []bool{true, false, true}, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ {[]string{"foo", "bar"}, nil, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToBoolSliceE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToBoolSlice(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToIntSliceE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect []int
+ iserr bool
+ }{
+ {[]int{1, 3}, []int{1, 3}, false},
+ {[]interface{}{1.2, 3.2}, []int{1, 3}, false},
+ {[]string{"2", "3"}, []int{2, 3}, false},
+ {[2]string{"2", "3"}, []int{2, 3}, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ {[]string{"foo", "bar"}, nil, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToIntSliceE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToIntSlice(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToSliceE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect []interface{}
+ iserr bool
+ }{
+ {[]interface{}{1, 3}, []interface{}{1, 3}, false},
+ {[]map[string]interface{}{{"k1": 1}, {"k2": 2}}, []interface{}{map[string]interface{}{"k1": 1}, map[string]interface{}{"k2": 2}}, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToSliceE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToSlice(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToStringSliceE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect []string
+ iserr bool
+ }{
+ {[]string{"a", "b"}, []string{"a", "b"}, false},
+ {[]interface{}{1, 3}, []string{"1", "3"}, false},
+ {interface{}(1), []string{"1"}, false},
+ // errors
+ {nil, nil, true},
+ {testing.T{}, nil, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToStringSliceE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToStringSlice(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func TestToBoolE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect bool
+ iserr bool
+ }{
+ {0, false, false},
+ {nil, false, false},
+ {"false", false, false},
+ {"FALSE", false, false},
+ {"False", false, false},
+ {"f", false, false},
+ {"F", false, false},
+ {false, false, false},
+
+ {"true", true, false},
+ {"TRUE", true, false},
+ {"True", true, false},
+ {"t", true, false},
+ {"T", true, false},
+ {1, true, false},
+ {true, true, false},
+ {-1, true, false},
+
+ // errors
+ {"test", false, true},
+ {testing.T{}, false, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToBoolE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToBool(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
+
+func BenchmarkTooBool(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ if !ToBool(true) {
+ b.Fatal("ToBool returned false")
+ }
+ }
+}
+
+func TestIndirectPointers(t *testing.T) {
+ x := 13
+ y := &x
+ z := &y
+
+ assert.Equal(t, ToInt(y), 13)
+ assert.Equal(t, ToInt(z), 13)
+}
+
+func TestToTimeEE(t *testing.T) {
+ tests := []struct {
+ input interface{}
+ expect time.Time
+ iserr bool
+ }{
+ {"2009-11-10 23:00:00 +0000 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // Time.String()
+ {"Tue Nov 10 23:00:00 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // ANSIC
+ {"Tue Nov 10 23:00:00 UTC 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // UnixDate
+ {"Tue Nov 10 23:00:00 +0000 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RubyDate
+ {"10 Nov 09 23:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC822
+ {"10 Nov 09 23:00 +0000", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC822Z
+ {"Tuesday, 10-Nov-09 23:00:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC850
+ {"Tue, 10 Nov 2009 23:00:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC1123
+ {"Tue, 10 Nov 2009 23:00:00 +0000", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC1123Z
+ {"2009-11-10T23:00:00Z", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC3339
+ {"2009-11-10T23:00:00Z", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // RFC3339Nano
+ {"11:00PM", time.Date(0, 1, 1, 23, 0, 0, 0, time.UTC), false}, // Kitchen
+ {"Nov 10 23:00:00", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // Stamp
+ {"Nov 10 23:00:00.000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // StampMilli
+ {"Nov 10 23:00:00.000000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // StampMicro
+ {"Nov 10 23:00:00.000000000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false}, // StampNano
+ {"2016-03-06 15:28:01-00:00", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false}, // RFC3339 without T
+ {"2016-03-06 15:28:01", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
+ {"2016-03-06 15:28:01 -0000", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
+ {"2016-03-06 15:28:01 -00:00", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
+ {"2006-01-02", time.Date(2006, 1, 2, 0, 0, 0, 0, time.UTC), false},
+ {"02 Jan 2006", time.Date(2006, 1, 2, 0, 0, 0, 0, time.UTC), false},
+ {1472574600, time.Date(2016, 8, 30, 16, 30, 0, 0, time.UTC), false},
+ {int(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
+ {int64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
+ {int32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
+ {uint(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
+ {uint64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
+ {uint32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
+ {time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
+ // errors
+ {"2006", time.Time{}, true},
+ {testing.T{}, time.Time{}, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToTimeE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v.UTC(), errmsg)
+
+ // Non-E test
+ v = ToTime(test.input)
+ assert.Equal(t, test.expect, v.UTC(), errmsg)
+ }
+}
+
+func TestToDurationE(t *testing.T) {
+ var td time.Duration = 5
+
+ tests := []struct {
+ input interface{}
+ expect time.Duration
+ iserr bool
+ }{
+ {time.Duration(5), td, false},
+ {int(5), td, false},
+ {int64(5), td, false},
+ {int32(5), td, false},
+ {int16(5), td, false},
+ {int8(5), td, false},
+ {uint(5), td, false},
+ {uint64(5), td, false},
+ {uint32(5), td, false},
+ {uint16(5), td, false},
+ {uint8(5), td, false},
+ {float64(5), td, false},
+ {float32(5), td, false},
+ {string("5"), td, false},
+ {string("5ns"), td, false},
+ {string("5us"), time.Microsecond * td, false},
+ {string("5µs"), time.Microsecond * td, false},
+ {string("5ms"), time.Millisecond * td, false},
+ {string("5s"), time.Second * td, false},
+ {string("5m"), time.Minute * td, false},
+ {string("5h"), time.Hour * td, false},
+ // errors
+ {"test", 0, true},
+ {testing.T{}, 0, true},
+ }
+
+ for i, test := range tests {
+ errmsg := fmt.Sprintf("i = %d", i) // assert helper message
+
+ v, err := ToDurationE(test.input)
+ if test.iserr {
+ assert.Error(t, err, errmsg)
+ continue
+ }
+
+ assert.NoError(t, err, errmsg)
+ assert.Equal(t, test.expect, v, errmsg)
+
+ // Non-E test
+ v = ToDuration(test.input)
+ assert.Equal(t, test.expect, v, errmsg)
+ }
+}
diff --git a/vendor/github.com/spf13/cast/caste.go b/vendor/github.com/spf13/cast/caste.go
new file mode 100644
index 000000000..4e75f64ba
--- /dev/null
+++ b/vendor/github.com/spf13/cast/caste.go
@@ -0,0 +1,1117 @@
+// Copyright © 2014 Steve Francia <spf@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "errors"
+ "fmt"
+ "html/template"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var errNegativeNotAllowed = errors.New("unable to cast negative value")
+
+// ToTimeE casts an interface to a time.Time type.
+func ToTimeE(i interface{}) (tim time.Time, err error) {
+ i = indirect(i)
+
+ switch v := i.(type) {
+ case time.Time:
+ return v, nil
+ case string:
+ return StringToDate(v)
+ case int:
+ return time.Unix(int64(v), 0), nil
+ case int64:
+ return time.Unix(v, 0), nil
+ case int32:
+ return time.Unix(int64(v), 0), nil
+ case uint:
+ return time.Unix(int64(v), 0), nil
+ case uint64:
+ return time.Unix(int64(v), 0), nil
+ case uint32:
+ return time.Unix(int64(v), 0), nil
+ default:
+ return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
+ }
+}
+
+// ToDurationE casts an interface to a time.Duration type.
+func ToDurationE(i interface{}) (d time.Duration, err error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case time.Duration:
+ return s, nil
+ case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
+ d = time.Duration(ToInt64(s))
+ return
+ case float32, float64:
+ d = time.Duration(ToFloat64(s))
+ return
+ case string:
+ if strings.ContainsAny(s, "nsuµmh") {
+ d, err = time.ParseDuration(s)
+ } else {
+ d, err = time.ParseDuration(s + "ns")
+ }
+ return
+ default:
+ err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
+ return
+ }
+}
+
+// ToBoolE casts an interface to a bool type.
+func ToBoolE(i interface{}) (bool, error) {
+ i = indirect(i)
+
+ switch b := i.(type) {
+ case bool:
+ return b, nil
+ case nil:
+ return false, nil
+ case int:
+ if i.(int) != 0 {
+ return true, nil
+ }
+ return false, nil
+ case string:
+ return strconv.ParseBool(i.(string))
+ default:
+ return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
+ }
+}
+
+// ToFloat64E casts an interface to a float64 type.
+func ToFloat64E(i interface{}) (float64, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case float64:
+ return s, nil
+ case float32:
+ return float64(s), nil
+ case int:
+ return float64(s), nil
+ case int64:
+ return float64(s), nil
+ case int32:
+ return float64(s), nil
+ case int16:
+ return float64(s), nil
+ case int8:
+ return float64(s), nil
+ case uint:
+ return float64(s), nil
+ case uint64:
+ return float64(s), nil
+ case uint32:
+ return float64(s), nil
+ case uint16:
+ return float64(s), nil
+ case uint8:
+ return float64(s), nil
+ case string:
+ v, err := strconv.ParseFloat(s, 64)
+ if err == nil {
+ return v, nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
+ }
+}
+
+// ToFloat32E casts an interface to a float32 type.
+func ToFloat32E(i interface{}) (float32, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case float64:
+ return float32(s), nil
+ case float32:
+ return s, nil
+ case int:
+ return float32(s), nil
+ case int64:
+ return float32(s), nil
+ case int32:
+ return float32(s), nil
+ case int16:
+ return float32(s), nil
+ case int8:
+ return float32(s), nil
+ case uint:
+ return float32(s), nil
+ case uint64:
+ return float32(s), nil
+ case uint32:
+ return float32(s), nil
+ case uint16:
+ return float32(s), nil
+ case uint8:
+ return float32(s), nil
+ case string:
+ v, err := strconv.ParseFloat(s, 32)
+ if err == nil {
+ return float32(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
+ }
+}
+
+// ToInt64E casts an interface to an int64 type.
+func ToInt64E(i interface{}) (int64, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case int:
+ return int64(s), nil
+ case int64:
+ return s, nil
+ case int32:
+ return int64(s), nil
+ case int16:
+ return int64(s), nil
+ case int8:
+ return int64(s), nil
+ case uint:
+ return int64(s), nil
+ case uint64:
+ return int64(s), nil
+ case uint32:
+ return int64(s), nil
+ case uint16:
+ return int64(s), nil
+ case uint8:
+ return int64(s), nil
+ case float64:
+ return int64(s), nil
+ case float32:
+ return int64(s), nil
+ case string:
+ v, err := strconv.ParseInt(s, 0, 0)
+ if err == nil {
+ return v, nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
+ }
+}
+
+// ToInt32E casts an interface to an int32 type.
+func ToInt32E(i interface{}) (int32, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case int:
+ return int32(s), nil
+ case int64:
+ return int32(s), nil
+ case int32:
+ return s, nil
+ case int16:
+ return int32(s), nil
+ case int8:
+ return int32(s), nil
+ case uint:
+ return int32(s), nil
+ case uint64:
+ return int32(s), nil
+ case uint32:
+ return int32(s), nil
+ case uint16:
+ return int32(s), nil
+ case uint8:
+ return int32(s), nil
+ case float64:
+ return int32(s), nil
+ case float32:
+ return int32(s), nil
+ case string:
+ v, err := strconv.ParseInt(s, 0, 0)
+ if err == nil {
+ return int32(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
+ }
+}
+
+// ToInt16E casts an interface to an int16 type.
+func ToInt16E(i interface{}) (int16, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case int:
+ return int16(s), nil
+ case int64:
+ return int16(s), nil
+ case int32:
+ return int16(s), nil
+ case int16:
+ return s, nil
+ case int8:
+ return int16(s), nil
+ case uint:
+ return int16(s), nil
+ case uint64:
+ return int16(s), nil
+ case uint32:
+ return int16(s), nil
+ case uint16:
+ return int16(s), nil
+ case uint8:
+ return int16(s), nil
+ case float64:
+ return int16(s), nil
+ case float32:
+ return int16(s), nil
+ case string:
+ v, err := strconv.ParseInt(s, 0, 0)
+ if err == nil {
+ return int16(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
+ }
+}
+
+// ToInt8E casts an interface to an int8 type.
+func ToInt8E(i interface{}) (int8, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case int:
+ return int8(s), nil
+ case int64:
+ return int8(s), nil
+ case int32:
+ return int8(s), nil
+ case int16:
+ return int8(s), nil
+ case int8:
+ return s, nil
+ case uint:
+ return int8(s), nil
+ case uint64:
+ return int8(s), nil
+ case uint32:
+ return int8(s), nil
+ case uint16:
+ return int8(s), nil
+ case uint8:
+ return int8(s), nil
+ case float64:
+ return int8(s), nil
+ case float32:
+ return int8(s), nil
+ case string:
+ v, err := strconv.ParseInt(s, 0, 0)
+ if err == nil {
+ return int8(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
+ }
+}
+
+// ToIntE casts an interface to an int type.
+func ToIntE(i interface{}) (int, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case int:
+ return s, nil
+ case int64:
+ return int(s), nil
+ case int32:
+ return int(s), nil
+ case int16:
+ return int(s), nil
+ case int8:
+ return int(s), nil
+ case uint:
+ return int(s), nil
+ case uint64:
+ return int(s), nil
+ case uint32:
+ return int(s), nil
+ case uint16:
+ return int(s), nil
+ case uint8:
+ return int(s), nil
+ case float64:
+ return int(s), nil
+ case float32:
+ return int(s), nil
+ case string:
+ v, err := strconv.ParseInt(s, 0, 0)
+ if err == nil {
+ return int(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
+ }
+}
+
+// ToUintE casts an interface to a uint type.
+func ToUintE(i interface{}) (uint, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case string:
+ v, err := strconv.ParseUint(s, 0, 0)
+ if err == nil {
+ return uint(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
+ case int:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint(s), nil
+ case int64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint(s), nil
+ case int32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint(s), nil
+ case int16:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint(s), nil
+ case int8:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint(s), nil
+ case uint:
+ return s, nil
+ case uint64:
+ return uint(s), nil
+ case uint32:
+ return uint(s), nil
+ case uint16:
+ return uint(s), nil
+ case uint8:
+ return uint(s), nil
+ case float64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint(s), nil
+ case float32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint(s), nil
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
+ }
+}
+
+// ToUint64E casts an interface to a uint64 type.
+func ToUint64E(i interface{}) (uint64, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case string:
+ v, err := strconv.ParseUint(s, 0, 64)
+ if err == nil {
+ return v, nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
+ case int:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint64(s), nil
+ case int64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint64(s), nil
+ case int32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint64(s), nil
+ case int16:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint64(s), nil
+ case int8:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint64(s), nil
+ case uint:
+ return uint64(s), nil
+ case uint64:
+ return s, nil
+ case uint32:
+ return uint64(s), nil
+ case uint16:
+ return uint64(s), nil
+ case uint8:
+ return uint64(s), nil
+ case float32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint64(s), nil
+ case float64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint64(s), nil
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
+ }
+}
+
+// ToUint32E casts an interface to a uint32 type.
+func ToUint32E(i interface{}) (uint32, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case string:
+ v, err := strconv.ParseUint(s, 0, 32)
+ if err == nil {
+ return uint32(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
+ case int:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint32(s), nil
+ case int64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint32(s), nil
+ case int32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint32(s), nil
+ case int16:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint32(s), nil
+ case int8:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint32(s), nil
+ case uint:
+ return uint32(s), nil
+ case uint64:
+ return uint32(s), nil
+ case uint32:
+ return s, nil
+ case uint16:
+ return uint32(s), nil
+ case uint8:
+ return uint32(s), nil
+ case float64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint32(s), nil
+ case float32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint32(s), nil
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
+ }
+}
+
+// ToUint16E casts an interface to a uint16 type.
+func ToUint16E(i interface{}) (uint16, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case string:
+ v, err := strconv.ParseUint(s, 0, 16)
+ if err == nil {
+ return uint16(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
+ case int:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint16(s), nil
+ case int64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint16(s), nil
+ case int32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint16(s), nil
+ case int16:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint16(s), nil
+ case int8:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint16(s), nil
+ case uint:
+ return uint16(s), nil
+ case uint64:
+ return uint16(s), nil
+ case uint32:
+ return uint16(s), nil
+ case uint16:
+ return s, nil
+ case uint8:
+ return uint16(s), nil
+ case float64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint16(s), nil
+ case float32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint16(s), nil
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
+ }
+}
+
+// ToUint8E casts an interface to a uint type.
+func ToUint8E(i interface{}) (uint8, error) {
+ i = indirect(i)
+
+ switch s := i.(type) {
+ case string:
+ v, err := strconv.ParseUint(s, 0, 8)
+ if err == nil {
+ return uint8(v), nil
+ }
+ return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
+ case int:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint8(s), nil
+ case int64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint8(s), nil
+ case int32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint8(s), nil
+ case int16:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint8(s), nil
+ case int8:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint8(s), nil
+ case uint:
+ return uint8(s), nil
+ case uint64:
+ return uint8(s), nil
+ case uint32:
+ return uint8(s), nil
+ case uint16:
+ return uint8(s), nil
+ case uint8:
+ return s, nil
+ case float64:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint8(s), nil
+ case float32:
+ if s < 0 {
+ return 0, errNegativeNotAllowed
+ }
+ return uint8(s), nil
+ case bool:
+ if s {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
+ }
+}
+
+// From html/template/content.go
+// Copyright 2011 The Go Authors. All rights reserved.
+// indirect returns the value, after dereferencing as many times
+// as necessary to reach the base type (or nil).
+func indirect(a interface{}) interface{} {
+ if a == nil {
+ return nil
+ }
+ if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
+ // Avoid creating a reflect.Value if it's not a pointer.
+ return a
+ }
+ v := reflect.ValueOf(a)
+ for v.Kind() == reflect.Ptr && !v.IsNil() {
+ v = v.Elem()
+ }
+ return v.Interface()
+}
+
+// From html/template/content.go
+// Copyright 2011 The Go Authors. All rights reserved.
+// indirectToStringerOrError returns the value, after dereferencing as many times
+// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
+// or error,
+func indirectToStringerOrError(a interface{}) interface{} {
+ if a == nil {
+ return nil
+ }
+
+ var errorType = reflect.TypeOf((*error)(nil)).Elem()
+ var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
+
+ v := reflect.ValueOf(a)
+ for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
+ v = v.Elem()
+ }
+ return v.Interface()
+}
+
+// ToStringE casts an interface to a string type.
+func ToStringE(i interface{}) (string, error) {
+ i = indirectToStringerOrError(i)
+
+ switch s := i.(type) {
+ case string:
+ return s, nil
+ case bool:
+ return strconv.FormatBool(s), nil
+ case float64:
+ return strconv.FormatFloat(s, 'f', -1, 64), nil
+ case float32:
+ return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
+ case int:
+ return strconv.Itoa(s), nil
+ case int64:
+ return strconv.FormatInt(s, 10), nil
+ case int32:
+ return strconv.Itoa(int(s)), nil
+ case int16:
+ return strconv.FormatInt(int64(s), 10), nil
+ case int8:
+ return strconv.FormatInt(int64(s), 10), nil
+ case uint:
+ return strconv.FormatInt(int64(s), 10), nil
+ case uint64:
+ return strconv.FormatInt(int64(s), 10), nil
+ case uint32:
+ return strconv.FormatInt(int64(s), 10), nil
+ case uint16:
+ return strconv.FormatInt(int64(s), 10), nil
+ case uint8:
+ return strconv.FormatInt(int64(s), 10), nil
+ case []byte:
+ return string(s), nil
+ case template.HTML:
+ return string(s), nil
+ case template.URL:
+ return string(s), nil
+ case template.JS:
+ return string(s), nil
+ case template.CSS:
+ return string(s), nil
+ case template.HTMLAttr:
+ return string(s), nil
+ case nil:
+ return "", nil
+ case fmt.Stringer:
+ return s.String(), nil
+ case error:
+ return s.Error(), nil
+ default:
+ return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
+ }
+}
+
+// ToStringMapStringE casts an interface to a map[string]string type.
+func ToStringMapStringE(i interface{}) (map[string]string, error) {
+ var m = map[string]string{}
+
+ switch v := i.(type) {
+ case map[string]string:
+ return v, nil
+ case map[string]interface{}:
+ for k, val := range v {
+ m[ToString(k)] = ToString(val)
+ }
+ return m, nil
+ case map[interface{}]string:
+ for k, val := range v {
+ m[ToString(k)] = ToString(val)
+ }
+ return m, nil
+ case map[interface{}]interface{}:
+ for k, val := range v {
+ m[ToString(k)] = ToString(val)
+ }
+ return m, nil
+ default:
+ return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
+ }
+}
+
+// ToStringMapStringSliceE casts an interface to a map[string][]string type.
+func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
+ var m = map[string][]string{}
+
+ switch v := i.(type) {
+ case map[string][]string:
+ return v, nil
+ case map[string][]interface{}:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[string]string:
+ for k, val := range v {
+ m[ToString(k)] = []string{val}
+ }
+ case map[string]interface{}:
+ for k, val := range v {
+ switch vt := val.(type) {
+ case []interface{}:
+ m[ToString(k)] = ToStringSlice(vt)
+ case []string:
+ m[ToString(k)] = vt
+ default:
+ m[ToString(k)] = []string{ToString(val)}
+ }
+ }
+ return m, nil
+ case map[interface{}][]string:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[interface{}]string:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[interface{}][]interface{}:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[interface{}]interface{}:
+ for k, val := range v {
+ key, err := ToStringE(k)
+ if err != nil {
+ return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
+ }
+ value, err := ToStringSliceE(val)
+ if err != nil {
+ return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
+ }
+ m[key] = value
+ }
+ default:
+ return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
+ }
+ return m, nil
+}
+
+// ToStringMapBoolE casts an interface to a map[string]bool type.
+func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
+ var m = map[string]bool{}
+
+ switch v := i.(type) {
+ case map[interface{}]interface{}:
+ for k, val := range v {
+ m[ToString(k)] = ToBool(val)
+ }
+ return m, nil
+ case map[string]interface{}:
+ for k, val := range v {
+ m[ToString(k)] = ToBool(val)
+ }
+ return m, nil
+ case map[string]bool:
+ return v, nil
+ default:
+ return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
+ }
+}
+
+// ToStringMapE casts an interface to a map[string]interface{} type.
+func ToStringMapE(i interface{}) (map[string]interface{}, error) {
+ var m = map[string]interface{}{}
+
+ switch v := i.(type) {
+ case map[interface{}]interface{}:
+ for k, val := range v {
+ m[ToString(k)] = val
+ }
+ return m, nil
+ case map[string]interface{}:
+ return v, nil
+ default:
+ return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
+ }
+}
+
+// ToSliceE casts an interface to a []interface{} type.
+func ToSliceE(i interface{}) ([]interface{}, error) {
+ var s []interface{}
+
+ switch v := i.(type) {
+ case []interface{}:
+ return append(s, v...), nil
+ case []map[string]interface{}:
+ for _, u := range v {
+ s = append(s, u)
+ }
+ return s, nil
+ default:
+ return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
+ }
+}
+
+// ToBoolSliceE casts an interface to a []bool type.
+func ToBoolSliceE(i interface{}) ([]bool, error) {
+ if i == nil {
+ return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
+ }
+
+ switch v := i.(type) {
+ case []bool:
+ return v, nil
+ }
+
+ kind := reflect.TypeOf(i).Kind()
+ switch kind {
+ case reflect.Slice, reflect.Array:
+ s := reflect.ValueOf(i)
+ a := make([]bool, s.Len())
+ for j := 0; j < s.Len(); j++ {
+ val, err := ToBoolE(s.Index(j).Interface())
+ if err != nil {
+ return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
+ }
+ a[j] = val
+ }
+ return a, nil
+ default:
+ return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
+ }
+}
+
+// ToStringSliceE casts an interface to a []string type.
+func ToStringSliceE(i interface{}) ([]string, error) {
+ var a []string
+
+ switch v := i.(type) {
+ case []interface{}:
+ for _, u := range v {
+ a = append(a, ToString(u))
+ }
+ return a, nil
+ case []string:
+ return v, nil
+ case string:
+ return strings.Fields(v), nil
+ case interface{}:
+ str, err := ToStringE(v)
+ if err != nil {
+ return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
+ }
+ return []string{str}, nil
+ default:
+ return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
+ }
+}
+
+// ToIntSliceE casts an interface to a []int type.
+func ToIntSliceE(i interface{}) ([]int, error) {
+ if i == nil {
+ return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
+ }
+
+ switch v := i.(type) {
+ case []int:
+ return v, nil
+ }
+
+ kind := reflect.TypeOf(i).Kind()
+ switch kind {
+ case reflect.Slice, reflect.Array:
+ s := reflect.ValueOf(i)
+ a := make([]int, s.Len())
+ for j := 0; j < s.Len(); j++ {
+ val, err := ToIntE(s.Index(j).Interface())
+ if err != nil {
+ return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
+ }
+ a[j] = val
+ }
+ return a, nil
+ default:
+ return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
+ }
+}
+
+// StringToDate attempts to parse a string into a time.Time type using a
+// predefined list of formats. If no suitable format is found, an error is
+// returned.
+func StringToDate(s string) (time.Time, error) {
+ return parseDateWith(s, []string{
+ time.RFC3339,
+ "2006-01-02T15:04:05", // iso8601 without timezone
+ time.RFC1123Z,
+ time.RFC1123,
+ time.RFC822Z,
+ time.RFC822,
+ time.RFC850,
+ time.ANSIC,
+ time.UnixDate,
+ time.RubyDate,
+ "2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
+ "2006-01-02",
+ "02 Jan 2006",
+ "2006-01-02 15:04:05 -07:00",
+ "2006-01-02 15:04:05 -0700",
+ "2006-01-02 15:04:05Z07:00", // RFC3339 without T
+ "2006-01-02 15:04:05",
+ time.Kitchen,
+ time.Stamp,
+ time.StampMilli,
+ time.StampMicro,
+ time.StampNano,
+ })
+}
+
+func parseDateWith(s string, dates []string) (d time.Time, e error) {
+ for _, dateType := range dates {
+ if d, e = time.Parse(dateType, s); e == nil {
+ return
+ }
+ }
+ return d, fmt.Errorf("unable to parse date: %s", s)
+}