1// Copyright © 2014 Steve Francia <spf@spf13.com>.
2//
3// Use of this source code is governed by an MIT-style
4// license that can be found in the LICENSE file.
5
6package cast
7
8import (
9	"errors"
10	"fmt"
11	"html/template"
12	"reflect"
13	"strconv"
14	"strings"
15	"time"
16)
17
18var errNegativeNotAllowed = errors.New("unable to cast negative value")
19
20// ToTimeE casts an interface to a time.Time type.
21func ToTimeE(i interface{}) (tim time.Time, err error) {
22	i = indirect(i)
23
24	switch v := i.(type) {
25	case time.Time:
26		return v, nil
27	case string:
28		return StringToDate(v)
29	case int:
30		return time.Unix(int64(v), 0), nil
31	case int64:
32		return time.Unix(v, 0), nil
33	case int32:
34		return time.Unix(int64(v), 0), nil
35	case uint:
36		return time.Unix(int64(v), 0), nil
37	case uint64:
38		return time.Unix(int64(v), 0), nil
39	case uint32:
40		return time.Unix(int64(v), 0), nil
41	default:
42		return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
43	}
44}
45
46// ToDurationE casts an interface to a time.Duration type.
47func ToDurationE(i interface{}) (d time.Duration, err error) {
48	i = indirect(i)
49
50	switch s := i.(type) {
51	case time.Duration:
52		return s, nil
53	case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
54		d = time.Duration(ToInt64(s))
55		return
56	case float32, float64:
57		d = time.Duration(ToFloat64(s))
58		return
59	case string:
60		if strings.ContainsAny(s, "nsuµmh") {
61			d, err = time.ParseDuration(s)
62		} else {
63			d, err = time.ParseDuration(s + "ns")
64		}
65		return
66	default:
67		err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
68		return
69	}
70}
71
72// ToBoolE casts an interface to a bool type.
73func ToBoolE(i interface{}) (bool, error) {
74	i = indirect(i)
75
76	switch b := i.(type) {
77	case bool:
78		return b, nil
79	case nil:
80		return false, nil
81	case int:
82		if i.(int) != 0 {
83			return true, nil
84		}
85		return false, nil
86	case string:
87		return strconv.ParseBool(i.(string))
88	default:
89		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
90	}
91}
92
93// ToFloat64E casts an interface to a float64 type.
94func ToFloat64E(i interface{}) (float64, error) {
95	i = indirect(i)
96
97	switch s := i.(type) {
98	case float64:
99		return s, nil
100	case float32:
101		return float64(s), nil
102	case int:
103		return float64(s), nil
104	case int64:
105		return float64(s), nil
106	case int32:
107		return float64(s), nil
108	case int16:
109		return float64(s), nil
110	case int8:
111		return float64(s), nil
112	case uint:
113		return float64(s), nil
114	case uint64:
115		return float64(s), nil
116	case uint32:
117		return float64(s), nil
118	case uint16:
119		return float64(s), nil
120	case uint8:
121		return float64(s), nil
122	case string:
123		v, err := strconv.ParseFloat(s, 64)
124		if err == nil {
125			return v, nil
126		}
127		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
128	case bool:
129		if s {
130			return 1, nil
131		}
132		return 0, nil
133	default:
134		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
135	}
136}
137
138// ToFloat32E casts an interface to a float32 type.
139func ToFloat32E(i interface{}) (float32, error) {
140	i = indirect(i)
141
142	switch s := i.(type) {
143	case float64:
144		return float32(s), nil
145	case float32:
146		return s, nil
147	case int:
148		return float32(s), nil
149	case int64:
150		return float32(s), nil
151	case int32:
152		return float32(s), nil
153	case int16:
154		return float32(s), nil
155	case int8:
156		return float32(s), nil
157	case uint:
158		return float32(s), nil
159	case uint64:
160		return float32(s), nil
161	case uint32:
162		return float32(s), nil
163	case uint16:
164		return float32(s), nil
165	case uint8:
166		return float32(s), nil
167	case string:
168		v, err := strconv.ParseFloat(s, 32)
169		if err == nil {
170			return float32(v), nil
171		}
172		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
173	case bool:
174		if s {
175			return 1, nil
176		}
177		return 0, nil
178	default:
179		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
180	}
181}
182
183// ToInt64E casts an interface to an int64 type.
184func ToInt64E(i interface{}) (int64, error) {
185	i = indirect(i)
186
187	switch s := i.(type) {
188	case int:
189		return int64(s), nil
190	case int64:
191		return s, nil
192	case int32:
193		return int64(s), nil
194	case int16:
195		return int64(s), nil
196	case int8:
197		return int64(s), nil
198	case uint:
199		return int64(s), nil
200	case uint64:
201		return int64(s), nil
202	case uint32:
203		return int64(s), nil
204	case uint16:
205		return int64(s), nil
206	case uint8:
207		return int64(s), nil
208	case float64:
209		return int64(s), nil
210	case float32:
211		return int64(s), nil
212	case string:
213		v, err := strconv.ParseInt(s, 0, 0)
214		if err == nil {
215			return v, nil
216		}
217		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
218	case bool:
219		if s {
220			return 1, nil
221		}
222		return 0, nil
223	case nil:
224		return 0, nil
225	default:
226		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
227	}
228}
229
230// ToInt32E casts an interface to an int32 type.
231func ToInt32E(i interface{}) (int32, error) {
232	i = indirect(i)
233
234	switch s := i.(type) {
235	case int:
236		return int32(s), nil
237	case int64:
238		return int32(s), nil
239	case int32:
240		return s, nil
241	case int16:
242		return int32(s), nil
243	case int8:
244		return int32(s), nil
245	case uint:
246		return int32(s), nil
247	case uint64:
248		return int32(s), nil
249	case uint32:
250		return int32(s), nil
251	case uint16:
252		return int32(s), nil
253	case uint8:
254		return int32(s), nil
255	case float64:
256		return int32(s), nil
257	case float32:
258		return int32(s), nil
259	case string:
260		v, err := strconv.ParseInt(s, 0, 0)
261		if err == nil {
262			return int32(v), nil
263		}
264		return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
265	case bool:
266		if s {
267			return 1, nil
268		}
269		return 0, nil
270	case nil:
271		return 0, nil
272	default:
273		return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
274	}
275}
276
277// ToInt16E casts an interface to an int16 type.
278func ToInt16E(i interface{}) (int16, error) {
279	i = indirect(i)
280
281	switch s := i.(type) {
282	case int:
283		return int16(s), nil
284	case int64:
285		return int16(s), nil
286	case int32:
287		return int16(s), nil
288	case int16:
289		return s, nil
290	case int8:
291		return int16(s), nil
292	case uint:
293		return int16(s), nil
294	case uint64:
295		return int16(s), nil
296	case uint32:
297		return int16(s), nil
298	case uint16:
299		return int16(s), nil
300	case uint8:
301		return int16(s), nil
302	case float64:
303		return int16(s), nil
304	case float32:
305		return int16(s), nil
306	case string:
307		v, err := strconv.ParseInt(s, 0, 0)
308		if err == nil {
309			return int16(v), nil
310		}
311		return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
312	case bool:
313		if s {
314			return 1, nil
315		}
316		return 0, nil
317	case nil:
318		return 0, nil
319	default:
320		return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
321	}
322}
323
324// ToInt8E casts an interface to an int8 type.
325func ToInt8E(i interface{}) (int8, error) {
326	i = indirect(i)
327
328	switch s := i.(type) {
329	case int:
330		return int8(s), nil
331	case int64:
332		return int8(s), nil
333	case int32:
334		return int8(s), nil
335	case int16:
336		return int8(s), nil
337	case int8:
338		return s, nil
339	case uint:
340		return int8(s), nil
341	case uint64:
342		return int8(s), nil
343	case uint32:
344		return int8(s), nil
345	case uint16:
346		return int8(s), nil
347	case uint8:
348		return int8(s), nil
349	case float64:
350		return int8(s), nil
351	case float32:
352		return int8(s), nil
353	case string:
354		v, err := strconv.ParseInt(s, 0, 0)
355		if err == nil {
356			return int8(v), nil
357		}
358		return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
359	case bool:
360		if s {
361			return 1, nil
362		}
363		return 0, nil
364	case nil:
365		return 0, nil
366	default:
367		return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
368	}
369}
370
371// ToIntE casts an interface to an int type.
372func ToIntE(i interface{}) (int, error) {
373	i = indirect(i)
374
375	switch s := i.(type) {
376	case int:
377		return s, nil
378	case int64:
379		return int(s), nil
380	case int32:
381		return int(s), nil
382	case int16:
383		return int(s), nil
384	case int8:
385		return int(s), nil
386	case uint:
387		return int(s), nil
388	case uint64:
389		return int(s), nil
390	case uint32:
391		return int(s), nil
392	case uint16:
393		return int(s), nil
394	case uint8:
395		return int(s), nil
396	case float64:
397		return int(s), nil
398	case float32:
399		return int(s), nil
400	case string:
401		v, err := strconv.ParseInt(s, 0, 0)
402		if err == nil {
403			return int(v), nil
404		}
405		return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
406	case bool:
407		if s {
408			return 1, nil
409		}
410		return 0, nil
411	case nil:
412		return 0, nil
413	default:
414		return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
415	}
416}
417
418// ToUintE casts an interface to a uint type.
419func ToUintE(i interface{}) (uint, error) {
420	i = indirect(i)
421
422	switch s := i.(type) {
423	case string:
424		v, err := strconv.ParseUint(s, 0, 0)
425		if err == nil {
426			return uint(v), nil
427		}
428		return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
429	case int:
430		if s < 0 {
431			return 0, errNegativeNotAllowed
432		}
433		return uint(s), nil
434	case int64:
435		if s < 0 {
436			return 0, errNegativeNotAllowed
437		}
438		return uint(s), nil
439	case int32:
440		if s < 0 {
441			return 0, errNegativeNotAllowed
442		}
443		return uint(s), nil
444	case int16:
445		if s < 0 {
446			return 0, errNegativeNotAllowed
447		}
448		return uint(s), nil
449	case int8:
450		if s < 0 {
451			return 0, errNegativeNotAllowed
452		}
453		return uint(s), nil
454	case uint:
455		return s, nil
456	case uint64:
457		return uint(s), nil
458	case uint32:
459		return uint(s), nil
460	case uint16:
461		return uint(s), nil
462	case uint8:
463		return uint(s), nil
464	case float64:
465		if s < 0 {
466			return 0, errNegativeNotAllowed
467		}
468		return uint(s), nil
469	case float32:
470		if s < 0 {
471			return 0, errNegativeNotAllowed
472		}
473		return uint(s), nil
474	case bool:
475		if s {
476			return 1, nil
477		}
478		return 0, nil
479	case nil:
480		return 0, nil
481	default:
482		return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
483	}
484}
485
486// ToUint64E casts an interface to a uint64 type.
487func ToUint64E(i interface{}) (uint64, error) {
488	i = indirect(i)
489
490	switch s := i.(type) {
491	case string:
492		v, err := strconv.ParseUint(s, 0, 64)
493		if err == nil {
494			return v, nil
495		}
496		return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
497	case int:
498		if s < 0 {
499			return 0, errNegativeNotAllowed
500		}
501		return uint64(s), nil
502	case int64:
503		if s < 0 {
504			return 0, errNegativeNotAllowed
505		}
506		return uint64(s), nil
507	case int32:
508		if s < 0 {
509			return 0, errNegativeNotAllowed
510		}
511		return uint64(s), nil
512	case int16:
513		if s < 0 {
514			return 0, errNegativeNotAllowed
515		}
516		return uint64(s), nil
517	case int8:
518		if s < 0 {
519			return 0, errNegativeNotAllowed
520		}
521		return uint64(s), nil
522	case uint:
523		return uint64(s), nil
524	case uint64:
525		return s, nil
526	case uint32:
527		return uint64(s), nil
528	case uint16:
529		return uint64(s), nil
530	case uint8:
531		return uint64(s), nil
532	case float32:
533		if s < 0 {
534			return 0, errNegativeNotAllowed
535		}
536		return uint64(s), nil
537	case float64:
538		if s < 0 {
539			return 0, errNegativeNotAllowed
540		}
541		return uint64(s), nil
542	case bool:
543		if s {
544			return 1, nil
545		}
546		return 0, nil
547	case nil:
548		return 0, nil
549	default:
550		return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
551	}
552}
553
554// ToUint32E casts an interface to a uint32 type.
555func ToUint32E(i interface{}) (uint32, error) {
556	i = indirect(i)
557
558	switch s := i.(type) {
559	case string:
560		v, err := strconv.ParseUint(s, 0, 32)
561		if err == nil {
562			return uint32(v), nil
563		}
564		return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
565	case int:
566		if s < 0 {
567			return 0, errNegativeNotAllowed
568		}
569		return uint32(s), nil
570	case int64:
571		if s < 0 {
572			return 0, errNegativeNotAllowed
573		}
574		return uint32(s), nil
575	case int32:
576		if s < 0 {
577			return 0, errNegativeNotAllowed
578		}
579		return uint32(s), nil
580	case int16:
581		if s < 0 {
582			return 0, errNegativeNotAllowed
583		}
584		return uint32(s), nil
585	case int8:
586		if s < 0 {
587			return 0, errNegativeNotAllowed
588		}
589		return uint32(s), nil
590	case uint:
591		return uint32(s), nil
592	case uint64:
593		return uint32(s), nil
594	case uint32:
595		return s, nil
596	case uint16:
597		return uint32(s), nil
598	case uint8:
599		return uint32(s), nil
600	case float64:
601		if s < 0 {
602			return 0, errNegativeNotAllowed
603		}
604		return uint32(s), nil
605	case float32:
606		if s < 0 {
607			return 0, errNegativeNotAllowed
608		}
609		return uint32(s), nil
610	case bool:
611		if s {
612			return 1, nil
613		}
614		return 0, nil
615	case nil:
616		return 0, nil
617	default:
618		return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
619	}
620}
621
622// ToUint16E casts an interface to a uint16 type.
623func ToUint16E(i interface{}) (uint16, error) {
624	i = indirect(i)
625
626	switch s := i.(type) {
627	case string:
628		v, err := strconv.ParseUint(s, 0, 16)
629		if err == nil {
630			return uint16(v), nil
631		}
632		return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
633	case int:
634		if s < 0 {
635			return 0, errNegativeNotAllowed
636		}
637		return uint16(s), nil
638	case int64:
639		if s < 0 {
640			return 0, errNegativeNotAllowed
641		}
642		return uint16(s), nil
643	case int32:
644		if s < 0 {
645			return 0, errNegativeNotAllowed
646		}
647		return uint16(s), nil
648	case int16:
649		if s < 0 {
650			return 0, errNegativeNotAllowed
651		}
652		return uint16(s), nil
653	case int8:
654		if s < 0 {
655			return 0, errNegativeNotAllowed
656		}
657		return uint16(s), nil
658	case uint:
659		return uint16(s), nil
660	case uint64:
661		return uint16(s), nil
662	case uint32:
663		return uint16(s), nil
664	case uint16:
665		return s, nil
666	case uint8:
667		return uint16(s), nil
668	case float64:
669		if s < 0 {
670			return 0, errNegativeNotAllowed
671		}
672		return uint16(s), nil
673	case float32:
674		if s < 0 {
675			return 0, errNegativeNotAllowed
676		}
677		return uint16(s), nil
678	case bool:
679		if s {
680			return 1, nil
681		}
682		return 0, nil
683	case nil:
684		return 0, nil
685	default:
686		return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
687	}
688}
689
690// ToUint8E casts an interface to a uint type.
691func ToUint8E(i interface{}) (uint8, error) {
692	i = indirect(i)
693
694	switch s := i.(type) {
695	case string:
696		v, err := strconv.ParseUint(s, 0, 8)
697		if err == nil {
698			return uint8(v), nil
699		}
700		return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
701	case int:
702		if s < 0 {
703			return 0, errNegativeNotAllowed
704		}
705		return uint8(s), nil
706	case int64:
707		if s < 0 {
708			return 0, errNegativeNotAllowed
709		}
710		return uint8(s), nil
711	case int32:
712		if s < 0 {
713			return 0, errNegativeNotAllowed
714		}
715		return uint8(s), nil
716	case int16:
717		if s < 0 {
718			return 0, errNegativeNotAllowed
719		}
720		return uint8(s), nil
721	case int8:
722		if s < 0 {
723			return 0, errNegativeNotAllowed
724		}
725		return uint8(s), nil
726	case uint:
727		return uint8(s), nil
728	case uint64:
729		return uint8(s), nil
730	case uint32:
731		return uint8(s), nil
732	case uint16:
733		return uint8(s), nil
734	case uint8:
735		return s, nil
736	case float64:
737		if s < 0 {
738			return 0, errNegativeNotAllowed
739		}
740		return uint8(s), nil
741	case float32:
742		if s < 0 {
743			return 0, errNegativeNotAllowed
744		}
745		return uint8(s), nil
746	case bool:
747		if s {
748			return 1, nil
749		}
750		return 0, nil
751	case nil:
752		return 0, nil
753	default:
754		return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
755	}
756}
757
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).
762func indirect(a interface{}) interface{} {
763	if a == nil {
764		return nil
765	}
766	if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
767		// Avoid creating a reflect.Value if it's not a pointer.
768		return a
769	}
770	v := reflect.ValueOf(a)
771	for v.Kind() == reflect.Ptr && !v.IsNil() {
772		v = v.Elem()
773	}
774	return v.Interface()
775}
776
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
781// or error,
782func indirectToStringerOrError(a interface{}) interface{} {
783	if a == nil {
784		return nil
785	}
786
787	var errorType = reflect.TypeOf((*error)(nil)).Elem()
788	var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
789
790	v := reflect.ValueOf(a)
791	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
792		v = v.Elem()
793	}
794	return v.Interface()
795}
796
797// ToStringE casts an interface to a string type.
798func ToStringE(i interface{}) (string, error) {
799	i = indirectToStringerOrError(i)
800
801	switch s := i.(type) {
802	case string:
803		return s, nil
804	case bool:
805		return strconv.FormatBool(s), nil
806	case float64:
807		return strconv.FormatFloat(s, 'f', -1, 64), nil
808	case float32:
809		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
810	case int:
811		return strconv.Itoa(s), nil
812	case int64:
813		return strconv.FormatInt(s, 10), nil
814	case int32:
815		return strconv.Itoa(int(s)), nil
816	case int16:
817		return strconv.FormatInt(int64(s), 10), nil
818	case int8:
819		return strconv.FormatInt(int64(s), 10), nil
820	case uint:
821		return strconv.FormatInt(int64(s), 10), nil
822	case uint64:
823		return strconv.FormatInt(int64(s), 10), nil
824	case uint32:
825		return strconv.FormatInt(int64(s), 10), nil
826	case uint16:
827		return strconv.FormatInt(int64(s), 10), nil
828	case uint8:
829		return strconv.FormatInt(int64(s), 10), nil
830	case []byte:
831		return string(s), nil
832	case template.HTML:
833		return string(s), nil
834	case template.URL:
835		return string(s), nil
836	case template.JS:
837		return string(s), nil
838	case template.CSS:
839		return string(s), nil
840	case template.HTMLAttr:
841		return string(s), nil
842	case nil:
843		return "", nil
844	case fmt.Stringer:
845		return s.String(), nil
846	case error:
847		return s.Error(), nil
848	default:
849		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
850	}
851}
852
853// ToStringMapStringE casts an interface to a map[string]string type.
854func ToStringMapStringE(i interface{}) (map[string]string, error) {
855	var m = map[string]string{}
856
857	switch v := i.(type) {
858	case map[string]string:
859		return v, nil
860	case map[string]interface{}:
861		for k, val := range v {
862			m[ToString(k)] = ToString(val)
863		}
864		return m, nil
865	case map[interface{}]string:
866		for k, val := range v {
867			m[ToString(k)] = ToString(val)
868		}
869		return m, nil
870	case map[interface{}]interface{}:
871		for k, val := range v {
872			m[ToString(k)] = ToString(val)
873		}
874		return m, nil
875	default:
876		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
877	}
878}
879
880// ToStringMapStringSliceE casts an interface to a map[string][]string type.
881func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
882	var m = map[string][]string{}
883
884	switch v := i.(type) {
885	case map[string][]string:
886		return v, nil
887	case map[string][]interface{}:
888		for k, val := range v {
889			m[ToString(k)] = ToStringSlice(val)
890		}
891		return m, nil
892	case map[string]string:
893		for k, val := range v {
894			m[ToString(k)] = []string{val}
895		}
896	case map[string]interface{}:
897		for k, val := range v {
898			switch vt := val.(type) {
899			case []interface{}:
900				m[ToString(k)] = ToStringSlice(vt)
901			case []string:
902				m[ToString(k)] = vt
903			default:
904				m[ToString(k)] = []string{ToString(val)}
905			}
906		}
907		return m, nil
908	case map[interface{}][]string:
909		for k, val := range v {
910			m[ToString(k)] = ToStringSlice(val)
911		}
912		return m, nil
913	case map[interface{}]string:
914		for k, val := range v {
915			m[ToString(k)] = ToStringSlice(val)
916		}
917		return m, nil
918	case map[interface{}][]interface{}:
919		for k, val := range v {
920			m[ToString(k)] = ToStringSlice(val)
921		}
922		return m, nil
923	case map[interface{}]interface{}:
924		for k, val := range v {
925			key, err := ToStringE(k)
926			if err != nil {
927				return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
928			}
929			value, err := ToStringSliceE(val)
930			if err != nil {
931				return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
932			}
933			m[key] = value
934		}
935	default:
936		return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
937	}
938	return m, nil
939}
940
941// ToStringMapBoolE casts an interface to a map[string]bool type.
942func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
943	var m = map[string]bool{}
944
945	switch v := i.(type) {
946	case map[interface{}]interface{}:
947		for k, val := range v {
948			m[ToString(k)] = ToBool(val)
949		}
950		return m, nil
951	case map[string]interface{}:
952		for k, val := range v {
953			m[ToString(k)] = ToBool(val)
954		}
955		return m, nil
956	case map[string]bool:
957		return v, nil
958	default:
959		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
960	}
961}
962
963// ToStringMapE casts an interface to a map[string]interface{} type.
964func ToStringMapE(i interface{}) (map[string]interface{}, error) {
965	var m = map[string]interface{}{}
966
967	switch v := i.(type) {
968	case map[interface{}]interface{}:
969		for k, val := range v {
970			m[ToString(k)] = val
971		}
972		return m, nil
973	case map[string]interface{}:
974		return v, nil
975	default:
976		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
977	}
978}
979
980// ToSliceE casts an interface to a []interface{} type.
981func ToSliceE(i interface{}) ([]interface{}, error) {
982	var s []interface{}
983
984	switch v := i.(type) {
985	case []interface{}:
986		return append(s, v...), nil
987	case []map[string]interface{}:
988		for _, u := range v {
989			s = append(s, u)
990		}
991		return s, nil
992	default:
993		return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
994	}
995}
996
997// ToBoolSliceE casts an interface to a []bool type.
998func ToBoolSliceE(i interface{}) ([]bool, error) {
999	if i == nil {
1000		return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1001	}
1002
1003	switch v := i.(type) {
1004	case []bool:
1005		return v, nil
1006	}
1007
1008	kind := reflect.TypeOf(i).Kind()
1009	switch 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())
1015			if err != nil {
1016				return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1017			}
1018			a[j] = val
1019		}
1020		return a, nil
1021	default:
1022		return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1023	}
1024}
1025
1026// ToStringSliceE casts an interface to a []string type.
1027func ToStringSliceE(i interface{}) ([]string, error) {
1028	var a []string
1029
1030	switch v := i.(type) {
1031	case []interface{}:
1032		for _, u := range v {
1033			a = append(a, ToString(u))
1034		}
1035		return a, nil
1036	case []string:
1037		return v, nil
1038	case string:
1039		return strings.Fields(v), nil
1040	case interface{}:
1041		str, err := ToStringE(v)
1042		if err != nil {
1043			return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1044		}
1045		return []string{str}, nil
1046	default:
1047		return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1048	}
1049}
1050
1051// ToIntSliceE casts an interface to a []int type.
1052func ToIntSliceE(i interface{}) ([]int, error) {
1053	if i == nil {
1054		return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1055	}
1056
1057	switch v := i.(type) {
1058	case []int:
1059		return v, nil
1060	}
1061
1062	kind := reflect.TypeOf(i).Kind()
1063	switch 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())
1069			if err != nil {
1070				return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1071			}
1072			a[j] = val
1073		}
1074		return a, nil
1075	default:
1076		return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1077	}
1078}
1079
1080// ToDurationSliceE casts an interface to a []time.Duration type.
1081func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
1082	if i == nil {
1083		return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1084	}
1085
1086	switch v := i.(type) {
1087	case []time.Duration:
1088		return v, nil
1089	}
1090
1091	kind := reflect.TypeOf(i).Kind()
1092	switch 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())
1098			if err != nil {
1099				return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1100			}
1101			a[j] = val
1102		}
1103		return a, nil
1104	default:
1105		return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1106	}
1107}
1108
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
1111// returned.
1112func StringToDate(s string) (time.Time, error) {
1113	return parseDateWith(s, []string{
1114		time.RFC3339,
1115		"2006-01-02T15:04:05", // iso8601 without timezone
1116		time.RFC1123Z,
1117		time.RFC1123,
1118		time.RFC822Z,
1119		time.RFC822,
1120		time.RFC850,
1121		time.ANSIC,
1122		time.UnixDate,
1123		time.RubyDate,
1124		"2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
1125		"2006-01-02",
1126		"02 Jan 2006",
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",
1131		time.Kitchen,
1132		time.Stamp,
1133		time.StampMilli,
1134		time.StampMicro,
1135		time.StampNano,
1136	})
1137}
1138
1139func 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 {
1142			return
1143		}
1144	}
1145	return d, fmt.Errorf("unable to parse date: %s", s)
1146}
1147