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