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