aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/spf13/cast/caste.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/spf13/cast/caste.go')
-rw-r--r--vendor/github.com/spf13/cast/caste.go500
1 files changed, 500 insertions, 0 deletions
diff --git a/vendor/github.com/spf13/cast/caste.go b/vendor/github.com/spf13/cast/caste.go
new file mode 100644
index 0000000..2377896
--- /dev/null
+++ b/vendor/github.com/spf13/cast/caste.go
@@ -0,0 +1,500 @@
+// 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"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+
+ jww "github.com/spf13/jwalterweatherman"
+)
+
+// ToTimeE casts an empty interface to time.Time.
+func ToTimeE(i interface{}) (tim time.Time, err error) {
+ i = indirect(i)
+ jww.DEBUG.Println("ToTimeE called on type:", reflect.TypeOf(i))
+
+ switch s := i.(type) {
+ case time.Time:
+ return s, nil
+ case string:
+ d, e := StringToDate(s)
+ if e == nil {
+ return d, nil
+ }
+ return time.Time{}, fmt.Errorf("Could not parse Date/Time format: %v\n", e)
+ default:
+ return time.Time{}, fmt.Errorf("Unable to Cast %#v to Time\n", i)
+ }
+}
+
+// ToDurationE casts an empty interface to time.Duration.
+func ToDurationE(i interface{}) (d time.Duration, err error) {
+ i = indirect(i)
+ jww.DEBUG.Println("ToDurationE called on type:", reflect.TypeOf(i))
+
+ switch s := i.(type) {
+ case time.Duration:
+ return s, nil
+ case int64:
+ d = time.Duration(s)
+ return
+ case float64:
+ d = time.Duration(s)
+ return
+ case string:
+ d, err = time.ParseDuration(s)
+ return
+ default:
+ err = fmt.Errorf("Unable to Cast %#v to Duration\n", i)
+ return
+ }
+}
+
+// ToBoolE casts an empty interface to a bool.
+func ToBoolE(i interface{}) (bool, error) {
+ i = indirect(i)
+ jww.DEBUG.Println("ToBoolE called on type:", reflect.TypeOf(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 to bool", i)
+ }
+}
+
+// ToFloat64E casts an empty interface to a float64.
+func ToFloat64E(i interface{}) (float64, error) {
+ i = indirect(i)
+ jww.DEBUG.Println("ToFloat64E called on type:", reflect.TypeOf(i))
+
+ switch s := i.(type) {
+ case float64:
+ return s, nil
+ case float32:
+ 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 int:
+ return float64(s), nil
+ case string:
+ v, err := strconv.ParseFloat(s, 64)
+ if err == nil {
+ return float64(v), nil
+ }
+ return 0.0, fmt.Errorf("Unable to Cast %#v to float", i)
+ default:
+ return 0.0, fmt.Errorf("Unable to Cast %#v to float", i)
+ }
+}
+
+// ToInt64E casts an empty interface to an int64.
+func ToInt64E(i interface{}) (int64, error) {
+ i = indirect(i)
+ jww.DEBUG.Println("ToInt64E called on type:", reflect.TypeOf(i))
+
+ switch s := i.(type) {
+ case int64:
+ return s, nil
+ case int:
+ return int64(s), nil
+ case int32:
+ return int64(s), nil
+ case int16:
+ return int64(s), nil
+ case int8:
+ 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 to int64", i)
+ case float64:
+ return int64(s), nil
+ case bool:
+ if bool(s) {
+ return int64(1), nil
+ }
+ return int64(0), nil
+ case nil:
+ return int64(0), nil
+ default:
+ return int64(0), fmt.Errorf("Unable to Cast %#v to int64", i)
+ }
+}
+
+// ToIntE casts an empty interface to an int.
+func ToIntE(i interface{}) (int, error) {
+ i = indirect(i)
+ jww.DEBUG.Println("ToIntE called on type:", reflect.TypeOf(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 string:
+ v, err := strconv.ParseInt(s, 0, 0)
+ if err == nil {
+ return int(v), nil
+ }
+ return 0, fmt.Errorf("Unable to Cast %#v to int", i)
+ case float64:
+ return int(s), nil
+ case bool:
+ if bool(s) {
+ return 1, nil
+ }
+ return 0, nil
+ case nil:
+ return 0, nil
+ default:
+ return 0, fmt.Errorf("Unable to Cast %#v to int", 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 empty interface to a string.
+func ToStringE(i interface{}) (string, error) {
+ i = indirectToStringerOrError(i)
+ jww.DEBUG.Println("ToStringE called on type:", reflect.TypeOf(i))
+
+ switch s := i.(type) {
+ case string:
+ return s, nil
+ case bool:
+ return strconv.FormatBool(s), nil
+ case float64:
+ return strconv.FormatFloat(i.(float64), 'f', -1, 64), nil
+ case int64:
+ return strconv.FormatInt(i.(int64), 10), nil
+ case int:
+ return strconv.FormatInt(int64(i.(int)), 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 to string", i)
+ }
+}
+
+// ToStringMapStringE casts an empty interface to a map[string]string.
+func ToStringMapStringE(i interface{}) (map[string]string, error) {
+ jww.DEBUG.Println("ToStringMapStringE called on type:", reflect.TypeOf(i))
+
+ 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 to map[string]string", i)
+ }
+}
+
+// ToStringMapStringSliceE casts an empty interface to a map[string][]string.
+func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
+ jww.DEBUG.Println("ToStringMapStringSliceE called on type:", reflect.TypeOf(i))
+
+ 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 {
+ 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 to map[string][]string", i)
+ }
+ value, err := ToStringSliceE(val)
+ if err != nil {
+ return m, fmt.Errorf("Unable to Cast %#v to map[string][]string", i)
+ }
+ m[key] = value
+ }
+ default:
+ return m, fmt.Errorf("Unable to Cast %#v to map[string][]string", i)
+ }
+ return m, nil
+}
+
+// ToStringMapBoolE casts an empty interface to a map[string]bool.
+func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
+ jww.DEBUG.Println("ToStringMapBoolE called on type:", reflect.TypeOf(i))
+
+ 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 to map[string]bool", i)
+ }
+}
+
+// ToStringMapE casts an empty interface to a map[string]interface{}.
+func ToStringMapE(i interface{}) (map[string]interface{}, error) {
+ jww.DEBUG.Println("ToStringMapE called on type:", reflect.TypeOf(i))
+
+ 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 to map[string]interface{}", i)
+ }
+}
+
+// ToSliceE casts an empty interface to a []interface{}.
+func ToSliceE(i interface{}) ([]interface{}, error) {
+ jww.DEBUG.Println("ToSliceE called on type:", reflect.TypeOf(i))
+
+ var s []interface{}
+
+ switch v := i.(type) {
+ case []interface{}:
+ for _, u := range v {
+ s = append(s, u)
+ }
+ return s, 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 %v to []interface{}", i, reflect.TypeOf(i))
+ }
+}
+
+// ToStringSliceE casts an empty interface to a []string.
+func ToStringSliceE(i interface{}) ([]string, error) {
+ jww.DEBUG.Println("ToStringSliceE called on type:", reflect.TypeOf(i))
+
+ 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 to []string", i)
+ }
+ return []string{str}, nil
+ default:
+ return a, fmt.Errorf("Unable to Cast %#v to []string", i)
+ }
+}
+
+// ToIntSliceE casts an empty interface to a []int.
+func ToIntSliceE(i interface{}) ([]int, error) {
+ jww.DEBUG.Println("ToIntSliceE called on type:", reflect.TypeOf(i))
+
+ if i == nil {
+ return []int{}, fmt.Errorf("Unable to Cast %#v to []int", 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 to []int", i)
+ }
+ a[j] = val
+ }
+ return a, nil
+ default:
+ return []int{}, fmt.Errorf("Unable to Cast %#v to []int", i)
+ }
+}
+
+// StringToDate casts an empty interface to a time.Time.
+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.ANSIC,
+ time.UnixDate,
+ time.RubyDate,
+ "2006-01-02 15:04:05Z07:00",
+ "02 Jan 06 15:04 MST",
+ "2006-01-02",
+ "02 Jan 2006",
+ "2006-01-02 15:04:05 -07:00",
+ "2006-01-02 15:04:05 -0700",
+ })
+}
+
+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)
+}