1 // Copyright © 2014 Steve Francia <spf@spf13.com>.
3 // Use of this source code is governed by an MIT-style
4 // license that can be found in the LICENSE file.
18 var errNegativeNotAllowed = errors.New("unable to cast negative value")
20 // ToTimeE casts an interface to a time.Time type.
21 func ToTimeE(i interface{}) (tim time.Time, err error) {
24 switch v := i.(type) {
28 return StringToDate(v)
30 return time.Unix(int64(v), 0), nil
32 return time.Unix(v, 0), nil
34 return time.Unix(int64(v), 0), nil
36 return time.Unix(int64(v), 0), nil
38 return time.Unix(int64(v), 0), nil
40 return time.Unix(int64(v), 0), nil
42 return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
46 // ToDurationE casts an interface to a time.Duration type.
47 func ToDurationE(i interface{}) (d time.Duration, err error) {
50 switch s := i.(type) {
53 case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
54 d = time.Duration(ToInt64(s))
56 case float32, float64:
57 d = time.Duration(ToFloat64(s))
60 if strings.ContainsAny(s, "nsuµmh") {
61 d, err = time.ParseDuration(s)
63 d, err = time.ParseDuration(s + "ns")
67 err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
72 // ToBoolE casts an interface to a bool type.
73 func ToBoolE(i interface{}) (bool, error) {
76 switch b := i.(type) {
87 return strconv.ParseBool(i.(string))
89 return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
93 // ToFloat64E casts an interface to a float64 type.
94 func ToFloat64E(i interface{}) (float64, error) {
97 switch s := i.(type) {
101 return float64(s), nil
103 return float64(s), nil
105 return float64(s), nil
107 return float64(s), nil
109 return float64(s), nil
111 return float64(s), nil
113 return float64(s), nil
115 return float64(s), nil
117 return float64(s), nil
119 return float64(s), nil
121 return float64(s), nil
123 v, err := strconv.ParseFloat(s, 64)
127 return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
134 return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
138 // ToFloat32E casts an interface to a float32 type.
139 func ToFloat32E(i interface{}) (float32, error) {
142 switch s := i.(type) {
144 return float32(s), nil
148 return float32(s), nil
150 return float32(s), nil
152 return float32(s), nil
154 return float32(s), nil
156 return float32(s), nil
158 return float32(s), nil
160 return float32(s), nil
162 return float32(s), nil
164 return float32(s), nil
166 return float32(s), nil
168 v, err := strconv.ParseFloat(s, 32)
170 return float32(v), nil
172 return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
179 return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
183 // ToInt64E casts an interface to an int64 type.
184 func ToInt64E(i interface{}) (int64, error) {
187 switch s := i.(type) {
213 v, err := strconv.ParseInt(s, 0, 0)
217 return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
226 return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
230 // ToInt32E casts an interface to an int32 type.
231 func ToInt32E(i interface{}) (int32, error) {
234 switch s := i.(type) {
260 v, err := strconv.ParseInt(s, 0, 0)
264 return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
273 return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
277 // ToInt16E casts an interface to an int16 type.
278 func ToInt16E(i interface{}) (int16, error) {
281 switch s := i.(type) {
307 v, err := strconv.ParseInt(s, 0, 0)
311 return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
320 return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
324 // ToInt8E casts an interface to an int8 type.
325 func ToInt8E(i interface{}) (int8, error) {
328 switch s := i.(type) {
354 v, err := strconv.ParseInt(s, 0, 0)
358 return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
367 return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
371 // ToIntE casts an interface to an int type.
372 func ToIntE(i interface{}) (int, error) {
375 switch s := i.(type) {
401 v, err := strconv.ParseInt(s, 0, 0)
405 return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
414 return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
418 // ToUintE casts an interface to a uint type.
419 func ToUintE(i interface{}) (uint, error) {
422 switch s := i.(type) {
424 v, err := strconv.ParseUint(s, 0, 0)
428 return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
431 return 0, errNegativeNotAllowed
436 return 0, errNegativeNotAllowed
441 return 0, errNegativeNotAllowed
446 return 0, errNegativeNotAllowed
451 return 0, errNegativeNotAllowed
466 return 0, errNegativeNotAllowed
471 return 0, errNegativeNotAllowed
482 return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
486 // ToUint64E casts an interface to a uint64 type.
487 func ToUint64E(i interface{}) (uint64, error) {
490 switch s := i.(type) {
492 v, err := strconv.ParseUint(s, 0, 64)
496 return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
499 return 0, errNegativeNotAllowed
501 return uint64(s), nil
504 return 0, errNegativeNotAllowed
506 return uint64(s), nil
509 return 0, errNegativeNotAllowed
511 return uint64(s), nil
514 return 0, errNegativeNotAllowed
516 return uint64(s), nil
519 return 0, errNegativeNotAllowed
521 return uint64(s), nil
523 return uint64(s), nil
527 return uint64(s), nil
529 return uint64(s), nil
531 return uint64(s), nil
534 return 0, errNegativeNotAllowed
536 return uint64(s), nil
539 return 0, errNegativeNotAllowed
541 return uint64(s), nil
550 return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
554 // ToUint32E casts an interface to a uint32 type.
555 func ToUint32E(i interface{}) (uint32, error) {
558 switch s := i.(type) {
560 v, err := strconv.ParseUint(s, 0, 32)
562 return uint32(v), nil
564 return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
567 return 0, errNegativeNotAllowed
569 return uint32(s), nil
572 return 0, errNegativeNotAllowed
574 return uint32(s), nil
577 return 0, errNegativeNotAllowed
579 return uint32(s), nil
582 return 0, errNegativeNotAllowed
584 return uint32(s), nil
587 return 0, errNegativeNotAllowed
589 return uint32(s), nil
591 return uint32(s), nil
593 return uint32(s), nil
597 return uint32(s), nil
599 return uint32(s), nil
602 return 0, errNegativeNotAllowed
604 return uint32(s), nil
607 return 0, errNegativeNotAllowed
609 return uint32(s), nil
618 return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
622 // ToUint16E casts an interface to a uint16 type.
623 func ToUint16E(i interface{}) (uint16, error) {
626 switch s := i.(type) {
628 v, err := strconv.ParseUint(s, 0, 16)
630 return uint16(v), nil
632 return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
635 return 0, errNegativeNotAllowed
637 return uint16(s), nil
640 return 0, errNegativeNotAllowed
642 return uint16(s), nil
645 return 0, errNegativeNotAllowed
647 return uint16(s), nil
650 return 0, errNegativeNotAllowed
652 return uint16(s), nil
655 return 0, errNegativeNotAllowed
657 return uint16(s), nil
659 return uint16(s), nil
661 return uint16(s), nil
663 return uint16(s), nil
667 return uint16(s), nil
670 return 0, errNegativeNotAllowed
672 return uint16(s), nil
675 return 0, errNegativeNotAllowed
677 return uint16(s), nil
686 return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
690 // ToUint8E casts an interface to a uint type.
691 func ToUint8E(i interface{}) (uint8, error) {
694 switch s := i.(type) {
696 v, err := strconv.ParseUint(s, 0, 8)
700 return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
703 return 0, errNegativeNotAllowed
708 return 0, errNegativeNotAllowed
713 return 0, errNegativeNotAllowed
718 return 0, errNegativeNotAllowed
723 return 0, errNegativeNotAllowed
738 return 0, errNegativeNotAllowed
743 return 0, errNegativeNotAllowed
754 return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
758 // From html/template/content.go
759 // Copyright 2011 The Go Authors. All rights reserved.
760 // indirect returns the value, after dereferencing as many times
761 // as necessary to reach the base type (or nil).
762 func indirect(a interface{}) interface{} {
766 if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
767 // Avoid creating a reflect.Value if it's not a pointer.
770 v := reflect.ValueOf(a)
771 for v.Kind() == reflect.Ptr && !v.IsNil() {
777 // From html/template/content.go
778 // Copyright 2011 The Go Authors. All rights reserved.
779 // indirectToStringerOrError returns the value, after dereferencing as many times
780 // as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
782 func indirectToStringerOrError(a interface{}) interface{} {
787 var errorType = reflect.TypeOf((*error)(nil)).Elem()
788 var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
790 v := reflect.ValueOf(a)
791 for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
797 // ToStringE casts an interface to a string type.
798 func ToStringE(i interface{}) (string, error) {
799 i = indirectToStringerOrError(i)
801 switch s := i.(type) {
805 return strconv.FormatBool(s), nil
807 return strconv.FormatFloat(s, 'f', -1, 64), nil
809 return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
811 return strconv.Itoa(s), nil
813 return strconv.FormatInt(s, 10), nil
815 return strconv.Itoa(int(s)), nil
817 return strconv.FormatInt(int64(s), 10), nil
819 return strconv.FormatInt(int64(s), 10), nil
821 return strconv.FormatInt(int64(s), 10), nil
823 return strconv.FormatInt(int64(s), 10), nil
825 return strconv.FormatInt(int64(s), 10), nil
827 return strconv.FormatInt(int64(s), 10), nil
829 return strconv.FormatInt(int64(s), 10), nil
831 return string(s), nil
833 return string(s), nil
835 return string(s), nil
837 return string(s), nil
839 return string(s), nil
840 case template.HTMLAttr:
841 return string(s), nil
845 return s.String(), nil
847 return s.Error(), nil
849 return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
853 // ToStringMapStringE casts an interface to a map[string]string type.
854 func ToStringMapStringE(i interface{}) (map[string]string, error) {
855 var m = map[string]string{}
857 switch v := i.(type) {
858 case map[string]string:
860 case map[string]interface{}:
861 for k, val := range v {
862 m[ToString(k)] = ToString(val)
865 case map[interface{}]string:
866 for k, val := range v {
867 m[ToString(k)] = ToString(val)
870 case map[interface{}]interface{}:
871 for k, val := range v {
872 m[ToString(k)] = ToString(val)
876 return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
880 // ToStringMapStringSliceE casts an interface to a map[string][]string type.
881 func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
882 var m = map[string][]string{}
884 switch v := i.(type) {
885 case map[string][]string:
887 case map[string][]interface{}:
888 for k, val := range v {
889 m[ToString(k)] = ToStringSlice(val)
892 case map[string]string:
893 for k, val := range v {
894 m[ToString(k)] = []string{val}
896 case map[string]interface{}:
897 for k, val := range v {
898 switch vt := val.(type) {
900 m[ToString(k)] = ToStringSlice(vt)
904 m[ToString(k)] = []string{ToString(val)}
908 case map[interface{}][]string:
909 for k, val := range v {
910 m[ToString(k)] = ToStringSlice(val)
913 case map[interface{}]string:
914 for k, val := range v {
915 m[ToString(k)] = ToStringSlice(val)
918 case map[interface{}][]interface{}:
919 for k, val := range v {
920 m[ToString(k)] = ToStringSlice(val)
923 case map[interface{}]interface{}:
924 for k, val := range v {
925 key, err := ToStringE(k)
927 return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
929 value, err := ToStringSliceE(val)
931 return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
936 return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
941 // ToStringMapBoolE casts an interface to a map[string]bool type.
942 func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
943 var m = map[string]bool{}
945 switch v := i.(type) {
946 case map[interface{}]interface{}:
947 for k, val := range v {
948 m[ToString(k)] = ToBool(val)
951 case map[string]interface{}:
952 for k, val := range v {
953 m[ToString(k)] = ToBool(val)
956 case map[string]bool:
959 return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
963 // ToStringMapE casts an interface to a map[string]interface{} type.
964 func ToStringMapE(i interface{}) (map[string]interface{}, error) {
965 var m = map[string]interface{}{}
967 switch v := i.(type) {
968 case map[interface{}]interface{}:
969 for k, val := range v {
973 case map[string]interface{}:
976 return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
980 // ToSliceE casts an interface to a []interface{} type.
981 func ToSliceE(i interface{}) ([]interface{}, error) {
984 switch v := i.(type) {
986 return append(s, v...), nil
987 case []map[string]interface{}:
988 for _, u := range v {
993 return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
997 // ToBoolSliceE casts an interface to a []bool type.
998 func ToBoolSliceE(i interface{}) ([]bool, error) {
1000 return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1003 switch v := i.(type) {
1008 kind := reflect.TypeOf(i).Kind()
1010 case reflect.Slice, reflect.Array:
1011 s := reflect.ValueOf(i)
1012 a := make([]bool, s.Len())
1013 for j := 0; j < s.Len(); j++ {
1014 val, err := ToBoolE(s.Index(j).Interface())
1016 return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1022 return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1026 // ToStringSliceE casts an interface to a []string type.
1027 func ToStringSliceE(i interface{}) ([]string, error) {
1030 switch v := i.(type) {
1032 for _, u := range v {
1033 a = append(a, ToString(u))
1039 return strings.Fields(v), nil
1041 str, err := ToStringE(v)
1043 return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1045 return []string{str}, nil
1047 return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1051 // ToIntSliceE casts an interface to a []int type.
1052 func ToIntSliceE(i interface{}) ([]int, error) {
1054 return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1057 switch v := i.(type) {
1062 kind := reflect.TypeOf(i).Kind()
1064 case reflect.Slice, reflect.Array:
1065 s := reflect.ValueOf(i)
1066 a := make([]int, s.Len())
1067 for j := 0; j < s.Len(); j++ {
1068 val, err := ToIntE(s.Index(j).Interface())
1070 return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1076 return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1080 // ToDurationSliceE casts an interface to a []time.Duration type.
1081 func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
1083 return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1086 switch v := i.(type) {
1087 case []time.Duration:
1091 kind := reflect.TypeOf(i).Kind()
1093 case reflect.Slice, reflect.Array:
1094 s := reflect.ValueOf(i)
1095 a := make([]time.Duration, s.Len())
1096 for j := 0; j < s.Len(); j++ {
1097 val, err := ToDurationE(s.Index(j).Interface())
1099 return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1105 return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1109 // StringToDate attempts to parse a string into a time.Time type using a
1110 // predefined list of formats. If no suitable format is found, an error is
1112 func StringToDate(s string) (time.Time, error) {
1113 return parseDateWith(s, []string{
1115 "2006-01-02T15:04:05", // iso8601 without timezone
1124 "2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
1127 "2006-01-02 15:04:05 -07:00",
1128 "2006-01-02 15:04:05 -0700",
1129 "2006-01-02 15:04:05Z07:00", // RFC3339 without T
1130 "2006-01-02 15:04:05",
1139 func parseDateWith(s string, dates []string) (d time.Time, e error) {
1140 for _, dateType := range dates {
1141 if d, e = time.Parse(dateType, s); e == nil {
1145 return d, fmt.Errorf("unable to parse date: %s", s)