|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009 |
- // 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"
- )
-
- // 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 float64(v), nil
- }
- return 0.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.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 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 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 bool(s) {
- return int32(1), nil
- }
- return int32(0), nil
- case nil:
- return int32(0), nil
- default:
- return int32(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 bool(s) {
- return int16(1), nil
- }
- return int16(0), nil
- case nil:
- return int16(0), nil
- default:
- return int16(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 bool(s) {
- return int8(1), nil
- }
- return int8(0), nil
- case nil:
- return int8(0), nil
- default:
- return int8(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 bool(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:
- return uint(s), nil
- case int64:
- return uint(s), nil
- case int32:
- return uint(s), nil
- case int16:
- return uint(s), nil
- case int8:
- 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:
- return uint(s), nil
- case float32:
- 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:
- return uint64(s), nil
- case int64:
- return uint64(s), nil
- case int32:
- return uint64(s), nil
- case int16:
- return uint64(s), nil
- case int8:
- 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:
- return uint64(s), nil
- case float64:
- 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:
- return uint32(s), nil
- case int64:
- return uint32(s), nil
- case int32:
- return uint32(s), nil
- case int16:
- return uint32(s), nil
- case int8:
- 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:
- return uint32(s), nil
- case float32:
- 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:
- return uint16(s), nil
- case int64:
- return uint16(s), nil
- case int32:
- return uint16(s), nil
- case int16:
- return uint16(s), nil
- case int8:
- 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:
- return uint16(s), nil
- case float32:
- 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:
- return uint8(s), nil
- case int64:
- return uint8(s), nil
- case int32:
- return uint8(s), nil
- case int16:
- return uint8(s), nil
- case int8:
- 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:
- return uint8(s), nil
- case float32:
- 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)
- }
|