podman

Форк
0
1498 строк · 32.8 Кб
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

6
package cast
7

8
import (
9
	"encoding/json"
10
	"errors"
11
	"fmt"
12
	"html/template"
13
	"reflect"
14
	"strconv"
15
	"strings"
16
	"time"
17
)
18

19
var errNegativeNotAllowed = errors.New("unable to cast negative value")
20

21
// ToTimeE casts an interface to a time.Time type.
22
func ToTimeE(i interface{}) (tim time.Time, err error) {
23
	return ToTimeInDefaultLocationE(i, time.UTC)
24
}
25

26
// ToTimeInDefaultLocationE casts an empty interface to time.Time,
27
// interpreting inputs without a timezone to be in the given location,
28
// or the local timezone if nil.
29
func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.Time, err error) {
30
	i = indirect(i)
31

32
	switch v := i.(type) {
33
	case time.Time:
34
		return v, nil
35
	case string:
36
		return StringToDateInDefaultLocation(v, location)
37
	case json.Number:
38
		s, err1 := ToInt64E(v)
39
		if err1 != nil {
40
			return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
41
		}
42
		return time.Unix(s, 0), nil
43
	case int:
44
		return time.Unix(int64(v), 0), nil
45
	case int64:
46
		return time.Unix(v, 0), nil
47
	case int32:
48
		return time.Unix(int64(v), 0), nil
49
	case uint:
50
		return time.Unix(int64(v), 0), nil
51
	case uint64:
52
		return time.Unix(int64(v), 0), nil
53
	case uint32:
54
		return time.Unix(int64(v), 0), nil
55
	default:
56
		return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
57
	}
58
}
59

60
// ToDurationE casts an interface to a time.Duration type.
61
func ToDurationE(i interface{}) (d time.Duration, err error) {
62
	i = indirect(i)
63

64
	switch s := i.(type) {
65
	case time.Duration:
66
		return s, nil
67
	case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
68
		d = time.Duration(ToInt64(s))
69
		return
70
	case float32, float64:
71
		d = time.Duration(ToFloat64(s))
72
		return
73
	case string:
74
		if strings.ContainsAny(s, "nsuµmh") {
75
			d, err = time.ParseDuration(s)
76
		} else {
77
			d, err = time.ParseDuration(s + "ns")
78
		}
79
		return
80
	case json.Number:
81
		var v float64
82
		v, err = s.Float64()
83
		d = time.Duration(v)
84
		return
85
	default:
86
		err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
87
		return
88
	}
89
}
90

91
// ToBoolE casts an interface to a bool type.
92
func ToBoolE(i interface{}) (bool, error) {
93
	i = indirect(i)
94

95
	switch b := i.(type) {
96
	case bool:
97
		return b, nil
98
	case nil:
99
		return false, nil
100
	case int:
101
		return b != 0, nil
102
	case int64:
103
		return b != 0, nil
104
	case int32:
105
		return b != 0, nil
106
	case int16:
107
		return b != 0, nil
108
	case int8:
109
		return b != 0, nil
110
	case uint:
111
		return b != 0, nil
112
	case uint64:
113
		return b != 0, nil
114
	case uint32:
115
		return b != 0, nil
116
	case uint16:
117
		return b != 0, nil
118
	case uint8:
119
		return b != 0, nil
120
	case float64:
121
		return b != 0, nil
122
	case float32:
123
		return b != 0, nil
124
	case time.Duration:
125
		return b != 0, nil
126
	case string:
127
		return strconv.ParseBool(i.(string))
128
	case json.Number:
129
		v, err := ToInt64E(b)
130
		if err == nil {
131
			return v != 0, nil
132
		}
133
		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
134
	default:
135
		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
136
	}
137
}
138

139
// ToFloat64E casts an interface to a float64 type.
140
func ToFloat64E(i interface{}) (float64, error) {
141
	i = indirect(i)
142

143
	intv, ok := toInt(i)
144
	if ok {
145
		return float64(intv), nil
146
	}
147

148
	switch s := i.(type) {
149
	case float64:
150
		return s, nil
151
	case float32:
152
		return float64(s), nil
153
	case int64:
154
		return float64(s), nil
155
	case int32:
156
		return float64(s), nil
157
	case int16:
158
		return float64(s), nil
159
	case int8:
160
		return float64(s), nil
161
	case uint:
162
		return float64(s), nil
163
	case uint64:
164
		return float64(s), nil
165
	case uint32:
166
		return float64(s), nil
167
	case uint16:
168
		return float64(s), nil
169
	case uint8:
170
		return float64(s), nil
171
	case string:
172
		v, err := strconv.ParseFloat(s, 64)
173
		if err == nil {
174
			return v, nil
175
		}
176
		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
177
	case json.Number:
178
		v, err := s.Float64()
179
		if err == nil {
180
			return v, nil
181
		}
182
		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
183
	case bool:
184
		if s {
185
			return 1, nil
186
		}
187
		return 0, nil
188
	case nil:
189
		return 0, nil
190
	default:
191
		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
192
	}
193
}
194

195
// ToFloat32E casts an interface to a float32 type.
196
func ToFloat32E(i interface{}) (float32, error) {
197
	i = indirect(i)
198

199
	intv, ok := toInt(i)
200
	if ok {
201
		return float32(intv), nil
202
	}
203

204
	switch s := i.(type) {
205
	case float64:
206
		return float32(s), nil
207
	case float32:
208
		return s, nil
209
	case int64:
210
		return float32(s), nil
211
	case int32:
212
		return float32(s), nil
213
	case int16:
214
		return float32(s), nil
215
	case int8:
216
		return float32(s), nil
217
	case uint:
218
		return float32(s), nil
219
	case uint64:
220
		return float32(s), nil
221
	case uint32:
222
		return float32(s), nil
223
	case uint16:
224
		return float32(s), nil
225
	case uint8:
226
		return float32(s), nil
227
	case string:
228
		v, err := strconv.ParseFloat(s, 32)
229
		if err == nil {
230
			return float32(v), nil
231
		}
232
		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
233
	case json.Number:
234
		v, err := s.Float64()
235
		if err == nil {
236
			return float32(v), nil
237
		}
238
		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
239
	case bool:
240
		if s {
241
			return 1, nil
242
		}
243
		return 0, nil
244
	case nil:
245
		return 0, nil
246
	default:
247
		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
248
	}
249
}
250

251
// ToInt64E casts an interface to an int64 type.
252
func ToInt64E(i interface{}) (int64, error) {
253
	i = indirect(i)
254

255
	intv, ok := toInt(i)
256
	if ok {
257
		return int64(intv), nil
258
	}
259

260
	switch s := i.(type) {
261
	case int64:
262
		return s, nil
263
	case int32:
264
		return int64(s), nil
265
	case int16:
266
		return int64(s), nil
267
	case int8:
268
		return int64(s), nil
269
	case uint:
270
		return int64(s), nil
271
	case uint64:
272
		return int64(s), nil
273
	case uint32:
274
		return int64(s), nil
275
	case uint16:
276
		return int64(s), nil
277
	case uint8:
278
		return int64(s), nil
279
	case float64:
280
		return int64(s), nil
281
	case float32:
282
		return int64(s), nil
283
	case string:
284
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
285
		if err == nil {
286
			return v, nil
287
		}
288
		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
289
	case json.Number:
290
		return ToInt64E(string(s))
291
	case bool:
292
		if s {
293
			return 1, nil
294
		}
295
		return 0, nil
296
	case nil:
297
		return 0, nil
298
	default:
299
		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
300
	}
301
}
302

303
// ToInt32E casts an interface to an int32 type.
304
func ToInt32E(i interface{}) (int32, error) {
305
	i = indirect(i)
306

307
	intv, ok := toInt(i)
308
	if ok {
309
		return int32(intv), nil
310
	}
311

312
	switch s := i.(type) {
313
	case int64:
314
		return int32(s), nil
315
	case int32:
316
		return s, nil
317
	case int16:
318
		return int32(s), nil
319
	case int8:
320
		return int32(s), nil
321
	case uint:
322
		return int32(s), nil
323
	case uint64:
324
		return int32(s), nil
325
	case uint32:
326
		return int32(s), nil
327
	case uint16:
328
		return int32(s), nil
329
	case uint8:
330
		return int32(s), nil
331
	case float64:
332
		return int32(s), nil
333
	case float32:
334
		return int32(s), nil
335
	case string:
336
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
337
		if err == nil {
338
			return int32(v), nil
339
		}
340
		return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
341
	case json.Number:
342
		return ToInt32E(string(s))
343
	case bool:
344
		if s {
345
			return 1, nil
346
		}
347
		return 0, nil
348
	case nil:
349
		return 0, nil
350
	default:
351
		return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
352
	}
353
}
354

355
// ToInt16E casts an interface to an int16 type.
356
func ToInt16E(i interface{}) (int16, error) {
357
	i = indirect(i)
358

359
	intv, ok := toInt(i)
360
	if ok {
361
		return int16(intv), nil
362
	}
363

364
	switch s := i.(type) {
365
	case int64:
366
		return int16(s), nil
367
	case int32:
368
		return int16(s), nil
369
	case int16:
370
		return s, nil
371
	case int8:
372
		return int16(s), nil
373
	case uint:
374
		return int16(s), nil
375
	case uint64:
376
		return int16(s), nil
377
	case uint32:
378
		return int16(s), nil
379
	case uint16:
380
		return int16(s), nil
381
	case uint8:
382
		return int16(s), nil
383
	case float64:
384
		return int16(s), nil
385
	case float32:
386
		return int16(s), nil
387
	case string:
388
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
389
		if err == nil {
390
			return int16(v), nil
391
		}
392
		return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
393
	case json.Number:
394
		return ToInt16E(string(s))
395
	case bool:
396
		if s {
397
			return 1, nil
398
		}
399
		return 0, nil
400
	case nil:
401
		return 0, nil
402
	default:
403
		return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
404
	}
405
}
406

407
// ToInt8E casts an interface to an int8 type.
408
func ToInt8E(i interface{}) (int8, error) {
409
	i = indirect(i)
410

411
	intv, ok := toInt(i)
412
	if ok {
413
		return int8(intv), nil
414
	}
415

416
	switch s := i.(type) {
417
	case int64:
418
		return int8(s), nil
419
	case int32:
420
		return int8(s), nil
421
	case int16:
422
		return int8(s), nil
423
	case int8:
424
		return s, nil
425
	case uint:
426
		return int8(s), nil
427
	case uint64:
428
		return int8(s), nil
429
	case uint32:
430
		return int8(s), nil
431
	case uint16:
432
		return int8(s), nil
433
	case uint8:
434
		return int8(s), nil
435
	case float64:
436
		return int8(s), nil
437
	case float32:
438
		return int8(s), nil
439
	case string:
440
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
441
		if err == nil {
442
			return int8(v), nil
443
		}
444
		return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
445
	case json.Number:
446
		return ToInt8E(string(s))
447
	case bool:
448
		if s {
449
			return 1, nil
450
		}
451
		return 0, nil
452
	case nil:
453
		return 0, nil
454
	default:
455
		return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
456
	}
457
}
458

459
// ToIntE casts an interface to an int type.
460
func ToIntE(i interface{}) (int, error) {
461
	i = indirect(i)
462

463
	intv, ok := toInt(i)
464
	if ok {
465
		return intv, nil
466
	}
467

468
	switch s := i.(type) {
469
	case int64:
470
		return int(s), nil
471
	case int32:
472
		return int(s), nil
473
	case int16:
474
		return int(s), nil
475
	case int8:
476
		return int(s), nil
477
	case uint:
478
		return int(s), nil
479
	case uint64:
480
		return int(s), nil
481
	case uint32:
482
		return int(s), nil
483
	case uint16:
484
		return int(s), nil
485
	case uint8:
486
		return int(s), nil
487
	case float64:
488
		return int(s), nil
489
	case float32:
490
		return int(s), nil
491
	case string:
492
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
493
		if err == nil {
494
			return int(v), nil
495
		}
496
		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
497
	case json.Number:
498
		return ToIntE(string(s))
499
	case bool:
500
		if s {
501
			return 1, nil
502
		}
503
		return 0, nil
504
	case nil:
505
		return 0, nil
506
	default:
507
		return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
508
	}
509
}
510

511
// ToUintE casts an interface to a uint type.
512
func ToUintE(i interface{}) (uint, error) {
513
	i = indirect(i)
514

515
	intv, ok := toInt(i)
516
	if ok {
517
		if intv < 0 {
518
			return 0, errNegativeNotAllowed
519
		}
520
		return uint(intv), nil
521
	}
522

523
	switch s := i.(type) {
524
	case string:
525
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
526
		if err == nil {
527
			if v < 0 {
528
				return 0, errNegativeNotAllowed
529
			}
530
			return uint(v), nil
531
		}
532
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
533
	case json.Number:
534
		return ToUintE(string(s))
535
	case int64:
536
		if s < 0 {
537
			return 0, errNegativeNotAllowed
538
		}
539
		return uint(s), nil
540
	case int32:
541
		if s < 0 {
542
			return 0, errNegativeNotAllowed
543
		}
544
		return uint(s), nil
545
	case int16:
546
		if s < 0 {
547
			return 0, errNegativeNotAllowed
548
		}
549
		return uint(s), nil
550
	case int8:
551
		if s < 0 {
552
			return 0, errNegativeNotAllowed
553
		}
554
		return uint(s), nil
555
	case uint:
556
		return s, nil
557
	case uint64:
558
		return uint(s), nil
559
	case uint32:
560
		return uint(s), nil
561
	case uint16:
562
		return uint(s), nil
563
	case uint8:
564
		return uint(s), nil
565
	case float64:
566
		if s < 0 {
567
			return 0, errNegativeNotAllowed
568
		}
569
		return uint(s), nil
570
	case float32:
571
		if s < 0 {
572
			return 0, errNegativeNotAllowed
573
		}
574
		return uint(s), nil
575
	case bool:
576
		if s {
577
			return 1, nil
578
		}
579
		return 0, nil
580
	case nil:
581
		return 0, nil
582
	default:
583
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
584
	}
585
}
586

587
// ToUint64E casts an interface to a uint64 type.
588
func ToUint64E(i interface{}) (uint64, error) {
589
	i = indirect(i)
590

591
	intv, ok := toInt(i)
592
	if ok {
593
		if intv < 0 {
594
			return 0, errNegativeNotAllowed
595
		}
596
		return uint64(intv), nil
597
	}
598

599
	switch s := i.(type) {
600
	case string:
601
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
602
		if err == nil {
603
			if v < 0 {
604
				return 0, errNegativeNotAllowed
605
			}
606
			return uint64(v), nil
607
		}
608
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
609
	case json.Number:
610
		return ToUint64E(string(s))
611
	case int64:
612
		if s < 0 {
613
			return 0, errNegativeNotAllowed
614
		}
615
		return uint64(s), nil
616
	case int32:
617
		if s < 0 {
618
			return 0, errNegativeNotAllowed
619
		}
620
		return uint64(s), nil
621
	case int16:
622
		if s < 0 {
623
			return 0, errNegativeNotAllowed
624
		}
625
		return uint64(s), nil
626
	case int8:
627
		if s < 0 {
628
			return 0, errNegativeNotAllowed
629
		}
630
		return uint64(s), nil
631
	case uint:
632
		return uint64(s), nil
633
	case uint64:
634
		return s, nil
635
	case uint32:
636
		return uint64(s), nil
637
	case uint16:
638
		return uint64(s), nil
639
	case uint8:
640
		return uint64(s), nil
641
	case float32:
642
		if s < 0 {
643
			return 0, errNegativeNotAllowed
644
		}
645
		return uint64(s), nil
646
	case float64:
647
		if s < 0 {
648
			return 0, errNegativeNotAllowed
649
		}
650
		return uint64(s), nil
651
	case bool:
652
		if s {
653
			return 1, nil
654
		}
655
		return 0, nil
656
	case nil:
657
		return 0, nil
658
	default:
659
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
660
	}
661
}
662

663
// ToUint32E casts an interface to a uint32 type.
664
func ToUint32E(i interface{}) (uint32, error) {
665
	i = indirect(i)
666

667
	intv, ok := toInt(i)
668
	if ok {
669
		if intv < 0 {
670
			return 0, errNegativeNotAllowed
671
		}
672
		return uint32(intv), nil
673
	}
674

675
	switch s := i.(type) {
676
	case string:
677
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
678
		if err == nil {
679
			if v < 0 {
680
				return 0, errNegativeNotAllowed
681
			}
682
			return uint32(v), nil
683
		}
684
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
685
	case json.Number:
686
		return ToUint32E(string(s))
687
	case int64:
688
		if s < 0 {
689
			return 0, errNegativeNotAllowed
690
		}
691
		return uint32(s), nil
692
	case int32:
693
		if s < 0 {
694
			return 0, errNegativeNotAllowed
695
		}
696
		return uint32(s), nil
697
	case int16:
698
		if s < 0 {
699
			return 0, errNegativeNotAllowed
700
		}
701
		return uint32(s), nil
702
	case int8:
703
		if s < 0 {
704
			return 0, errNegativeNotAllowed
705
		}
706
		return uint32(s), nil
707
	case uint:
708
		return uint32(s), nil
709
	case uint64:
710
		return uint32(s), nil
711
	case uint32:
712
		return s, nil
713
	case uint16:
714
		return uint32(s), nil
715
	case uint8:
716
		return uint32(s), nil
717
	case float64:
718
		if s < 0 {
719
			return 0, errNegativeNotAllowed
720
		}
721
		return uint32(s), nil
722
	case float32:
723
		if s < 0 {
724
			return 0, errNegativeNotAllowed
725
		}
726
		return uint32(s), nil
727
	case bool:
728
		if s {
729
			return 1, nil
730
		}
731
		return 0, nil
732
	case nil:
733
		return 0, nil
734
	default:
735
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
736
	}
737
}
738

739
// ToUint16E casts an interface to a uint16 type.
740
func ToUint16E(i interface{}) (uint16, error) {
741
	i = indirect(i)
742

743
	intv, ok := toInt(i)
744
	if ok {
745
		if intv < 0 {
746
			return 0, errNegativeNotAllowed
747
		}
748
		return uint16(intv), nil
749
	}
750

751
	switch s := i.(type) {
752
	case string:
753
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
754
		if err == nil {
755
			if v < 0 {
756
				return 0, errNegativeNotAllowed
757
			}
758
			return uint16(v), nil
759
		}
760
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
761
	case json.Number:
762
		return ToUint16E(string(s))
763
	case int64:
764
		if s < 0 {
765
			return 0, errNegativeNotAllowed
766
		}
767
		return uint16(s), nil
768
	case int32:
769
		if s < 0 {
770
			return 0, errNegativeNotAllowed
771
		}
772
		return uint16(s), nil
773
	case int16:
774
		if s < 0 {
775
			return 0, errNegativeNotAllowed
776
		}
777
		return uint16(s), nil
778
	case int8:
779
		if s < 0 {
780
			return 0, errNegativeNotAllowed
781
		}
782
		return uint16(s), nil
783
	case uint:
784
		return uint16(s), nil
785
	case uint64:
786
		return uint16(s), nil
787
	case uint32:
788
		return uint16(s), nil
789
	case uint16:
790
		return s, nil
791
	case uint8:
792
		return uint16(s), nil
793
	case float64:
794
		if s < 0 {
795
			return 0, errNegativeNotAllowed
796
		}
797
		return uint16(s), nil
798
	case float32:
799
		if s < 0 {
800
			return 0, errNegativeNotAllowed
801
		}
802
		return uint16(s), nil
803
	case bool:
804
		if s {
805
			return 1, nil
806
		}
807
		return 0, nil
808
	case nil:
809
		return 0, nil
810
	default:
811
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
812
	}
813
}
814

815
// ToUint8E casts an interface to a uint type.
816
func ToUint8E(i interface{}) (uint8, error) {
817
	i = indirect(i)
818

819
	intv, ok := toInt(i)
820
	if ok {
821
		if intv < 0 {
822
			return 0, errNegativeNotAllowed
823
		}
824
		return uint8(intv), nil
825
	}
826

827
	switch s := i.(type) {
828
	case string:
829
		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
830
		if err == nil {
831
			if v < 0 {
832
				return 0, errNegativeNotAllowed
833
			}
834
			return uint8(v), nil
835
		}
836
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
837
	case json.Number:
838
		return ToUint8E(string(s))
839
	case int64:
840
		if s < 0 {
841
			return 0, errNegativeNotAllowed
842
		}
843
		return uint8(s), nil
844
	case int32:
845
		if s < 0 {
846
			return 0, errNegativeNotAllowed
847
		}
848
		return uint8(s), nil
849
	case int16:
850
		if s < 0 {
851
			return 0, errNegativeNotAllowed
852
		}
853
		return uint8(s), nil
854
	case int8:
855
		if s < 0 {
856
			return 0, errNegativeNotAllowed
857
		}
858
		return uint8(s), nil
859
	case uint:
860
		return uint8(s), nil
861
	case uint64:
862
		return uint8(s), nil
863
	case uint32:
864
		return uint8(s), nil
865
	case uint16:
866
		return uint8(s), nil
867
	case uint8:
868
		return s, nil
869
	case float64:
870
		if s < 0 {
871
			return 0, errNegativeNotAllowed
872
		}
873
		return uint8(s), nil
874
	case float32:
875
		if s < 0 {
876
			return 0, errNegativeNotAllowed
877
		}
878
		return uint8(s), nil
879
	case bool:
880
		if s {
881
			return 1, nil
882
		}
883
		return 0, nil
884
	case nil:
885
		return 0, nil
886
	default:
887
		return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
888
	}
889
}
890

891
// From html/template/content.go
892
// Copyright 2011 The Go Authors. All rights reserved.
893
// indirect returns the value, after dereferencing as many times
894
// as necessary to reach the base type (or nil).
895
func indirect(a interface{}) interface{} {
896
	if a == nil {
897
		return nil
898
	}
899
	if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
900
		// Avoid creating a reflect.Value if it's not a pointer.
901
		return a
902
	}
903
	v := reflect.ValueOf(a)
904
	for v.Kind() == reflect.Ptr && !v.IsNil() {
905
		v = v.Elem()
906
	}
907
	return v.Interface()
908
}
909

910
// From html/template/content.go
911
// Copyright 2011 The Go Authors. All rights reserved.
912
// indirectToStringerOrError returns the value, after dereferencing as many times
913
// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
914
// or error,
915
func indirectToStringerOrError(a interface{}) interface{} {
916
	if a == nil {
917
		return nil
918
	}
919

920
	var errorType = reflect.TypeOf((*error)(nil)).Elem()
921
	var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
922

923
	v := reflect.ValueOf(a)
924
	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
925
		v = v.Elem()
926
	}
927
	return v.Interface()
928
}
929

930
// ToStringE casts an interface to a string type.
931
func ToStringE(i interface{}) (string, error) {
932
	i = indirectToStringerOrError(i)
933

934
	switch s := i.(type) {
935
	case string:
936
		return s, nil
937
	case bool:
938
		return strconv.FormatBool(s), nil
939
	case float64:
940
		return strconv.FormatFloat(s, 'f', -1, 64), nil
941
	case float32:
942
		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
943
	case int:
944
		return strconv.Itoa(s), nil
945
	case int64:
946
		return strconv.FormatInt(s, 10), nil
947
	case int32:
948
		return strconv.Itoa(int(s)), nil
949
	case int16:
950
		return strconv.FormatInt(int64(s), 10), nil
951
	case int8:
952
		return strconv.FormatInt(int64(s), 10), nil
953
	case uint:
954
		return strconv.FormatUint(uint64(s), 10), nil
955
	case uint64:
956
		return strconv.FormatUint(uint64(s), 10), nil
957
	case uint32:
958
		return strconv.FormatUint(uint64(s), 10), nil
959
	case uint16:
960
		return strconv.FormatUint(uint64(s), 10), nil
961
	case uint8:
962
		return strconv.FormatUint(uint64(s), 10), nil
963
	case json.Number:
964
		return s.String(), nil
965
	case []byte:
966
		return string(s), nil
967
	case template.HTML:
968
		return string(s), nil
969
	case template.URL:
970
		return string(s), nil
971
	case template.JS:
972
		return string(s), nil
973
	case template.CSS:
974
		return string(s), nil
975
	case template.HTMLAttr:
976
		return string(s), nil
977
	case nil:
978
		return "", nil
979
	case fmt.Stringer:
980
		return s.String(), nil
981
	case error:
982
		return s.Error(), nil
983
	default:
984
		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
985
	}
986
}
987

988
// ToStringMapStringE casts an interface to a map[string]string type.
989
func ToStringMapStringE(i interface{}) (map[string]string, error) {
990
	var m = map[string]string{}
991

992
	switch v := i.(type) {
993
	case map[string]string:
994
		return v, nil
995
	case map[string]interface{}:
996
		for k, val := range v {
997
			m[ToString(k)] = ToString(val)
998
		}
999
		return m, nil
1000
	case map[interface{}]string:
1001
		for k, val := range v {
1002
			m[ToString(k)] = ToString(val)
1003
		}
1004
		return m, nil
1005
	case map[interface{}]interface{}:
1006
		for k, val := range v {
1007
			m[ToString(k)] = ToString(val)
1008
		}
1009
		return m, nil
1010
	case string:
1011
		err := jsonStringToObject(v, &m)
1012
		return m, err
1013
	default:
1014
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
1015
	}
1016
}
1017

1018
// ToStringMapStringSliceE casts an interface to a map[string][]string type.
1019
func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
1020
	var m = map[string][]string{}
1021

1022
	switch v := i.(type) {
1023
	case map[string][]string:
1024
		return v, nil
1025
	case map[string][]interface{}:
1026
		for k, val := range v {
1027
			m[ToString(k)] = ToStringSlice(val)
1028
		}
1029
		return m, nil
1030
	case map[string]string:
1031
		for k, val := range v {
1032
			m[ToString(k)] = []string{val}
1033
		}
1034
	case map[string]interface{}:
1035
		for k, val := range v {
1036
			switch vt := val.(type) {
1037
			case []interface{}:
1038
				m[ToString(k)] = ToStringSlice(vt)
1039
			case []string:
1040
				m[ToString(k)] = vt
1041
			default:
1042
				m[ToString(k)] = []string{ToString(val)}
1043
			}
1044
		}
1045
		return m, nil
1046
	case map[interface{}][]string:
1047
		for k, val := range v {
1048
			m[ToString(k)] = ToStringSlice(val)
1049
		}
1050
		return m, nil
1051
	case map[interface{}]string:
1052
		for k, val := range v {
1053
			m[ToString(k)] = ToStringSlice(val)
1054
		}
1055
		return m, nil
1056
	case map[interface{}][]interface{}:
1057
		for k, val := range v {
1058
			m[ToString(k)] = ToStringSlice(val)
1059
		}
1060
		return m, nil
1061
	case map[interface{}]interface{}:
1062
		for k, val := range v {
1063
			key, err := ToStringE(k)
1064
			if err != nil {
1065
				return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
1066
			}
1067
			value, err := ToStringSliceE(val)
1068
			if err != nil {
1069
				return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
1070
			}
1071
			m[key] = value
1072
		}
1073
	case string:
1074
		err := jsonStringToObject(v, &m)
1075
		return m, err
1076
	default:
1077
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
1078
	}
1079
	return m, nil
1080
}
1081

1082
// ToStringMapBoolE casts an interface to a map[string]bool type.
1083
func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
1084
	var m = map[string]bool{}
1085

1086
	switch v := i.(type) {
1087
	case map[interface{}]interface{}:
1088
		for k, val := range v {
1089
			m[ToString(k)] = ToBool(val)
1090
		}
1091
		return m, nil
1092
	case map[string]interface{}:
1093
		for k, val := range v {
1094
			m[ToString(k)] = ToBool(val)
1095
		}
1096
		return m, nil
1097
	case map[string]bool:
1098
		return v, nil
1099
	case string:
1100
		err := jsonStringToObject(v, &m)
1101
		return m, err
1102
	default:
1103
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
1104
	}
1105
}
1106

1107
// ToStringMapE casts an interface to a map[string]interface{} type.
1108
func ToStringMapE(i interface{}) (map[string]interface{}, error) {
1109
	var m = map[string]interface{}{}
1110

1111
	switch v := i.(type) {
1112
	case map[interface{}]interface{}:
1113
		for k, val := range v {
1114
			m[ToString(k)] = val
1115
		}
1116
		return m, nil
1117
	case map[string]interface{}:
1118
		return v, nil
1119
	case string:
1120
		err := jsonStringToObject(v, &m)
1121
		return m, err
1122
	default:
1123
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
1124
	}
1125
}
1126

1127
// ToStringMapIntE casts an interface to a map[string]int{} type.
1128
func ToStringMapIntE(i interface{}) (map[string]int, error) {
1129
	var m = map[string]int{}
1130
	if i == nil {
1131
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1132
	}
1133

1134
	switch v := i.(type) {
1135
	case map[interface{}]interface{}:
1136
		for k, val := range v {
1137
			m[ToString(k)] = ToInt(val)
1138
		}
1139
		return m, nil
1140
	case map[string]interface{}:
1141
		for k, val := range v {
1142
			m[k] = ToInt(val)
1143
		}
1144
		return m, nil
1145
	case map[string]int:
1146
		return v, nil
1147
	case string:
1148
		err := jsonStringToObject(v, &m)
1149
		return m, err
1150
	}
1151

1152
	if reflect.TypeOf(i).Kind() != reflect.Map {
1153
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1154
	}
1155

1156
	mVal := reflect.ValueOf(m)
1157
	v := reflect.ValueOf(i)
1158
	for _, keyVal := range v.MapKeys() {
1159
		val, err := ToIntE(v.MapIndex(keyVal).Interface())
1160
		if err != nil {
1161
			return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1162
		}
1163
		mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
1164
	}
1165
	return m, nil
1166
}
1167

1168
// ToStringMapInt64E casts an interface to a map[string]int64{} type.
1169
func ToStringMapInt64E(i interface{}) (map[string]int64, error) {
1170
	var m = map[string]int64{}
1171
	if i == nil {
1172
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1173
	}
1174

1175
	switch v := i.(type) {
1176
	case map[interface{}]interface{}:
1177
		for k, val := range v {
1178
			m[ToString(k)] = ToInt64(val)
1179
		}
1180
		return m, nil
1181
	case map[string]interface{}:
1182
		for k, val := range v {
1183
			m[k] = ToInt64(val)
1184
		}
1185
		return m, nil
1186
	case map[string]int64:
1187
		return v, nil
1188
	case string:
1189
		err := jsonStringToObject(v, &m)
1190
		return m, err
1191
	}
1192

1193
	if reflect.TypeOf(i).Kind() != reflect.Map {
1194
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1195
	}
1196
	mVal := reflect.ValueOf(m)
1197
	v := reflect.ValueOf(i)
1198
	for _, keyVal := range v.MapKeys() {
1199
		val, err := ToInt64E(v.MapIndex(keyVal).Interface())
1200
		if err != nil {
1201
			return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1202
		}
1203
		mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
1204
	}
1205
	return m, nil
1206
}
1207

1208
// ToSliceE casts an interface to a []interface{} type.
1209
func ToSliceE(i interface{}) ([]interface{}, error) {
1210
	var s []interface{}
1211

1212
	switch v := i.(type) {
1213
	case []interface{}:
1214
		return append(s, v...), nil
1215
	case []map[string]interface{}:
1216
		for _, u := range v {
1217
			s = append(s, u)
1218
		}
1219
		return s, nil
1220
	default:
1221
		return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
1222
	}
1223
}
1224

1225
// ToBoolSliceE casts an interface to a []bool type.
1226
func ToBoolSliceE(i interface{}) ([]bool, error) {
1227
	if i == nil {
1228
		return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1229
	}
1230

1231
	switch v := i.(type) {
1232
	case []bool:
1233
		return v, nil
1234
	}
1235

1236
	kind := reflect.TypeOf(i).Kind()
1237
	switch kind {
1238
	case reflect.Slice, reflect.Array:
1239
		s := reflect.ValueOf(i)
1240
		a := make([]bool, s.Len())
1241
		for j := 0; j < s.Len(); j++ {
1242
			val, err := ToBoolE(s.Index(j).Interface())
1243
			if err != nil {
1244
				return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1245
			}
1246
			a[j] = val
1247
		}
1248
		return a, nil
1249
	default:
1250
		return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1251
	}
1252
}
1253

1254
// ToStringSliceE casts an interface to a []string type.
1255
func ToStringSliceE(i interface{}) ([]string, error) {
1256
	var a []string
1257

1258
	switch v := i.(type) {
1259
	case []interface{}:
1260
		for _, u := range v {
1261
			a = append(a, ToString(u))
1262
		}
1263
		return a, nil
1264
	case []string:
1265
		return v, nil
1266
	case []int8:
1267
		for _, u := range v {
1268
			a = append(a, ToString(u))
1269
		}
1270
		return a, nil
1271
	case []int:
1272
		for _, u := range v {
1273
			a = append(a, ToString(u))
1274
		}
1275
		return a, nil
1276
	case []int32:
1277
		for _, u := range v {
1278
			a = append(a, ToString(u))
1279
		}
1280
		return a, nil
1281
	case []int64:
1282
		for _, u := range v {
1283
			a = append(a, ToString(u))
1284
		}
1285
		return a, nil
1286
	case []float32:
1287
		for _, u := range v {
1288
			a = append(a, ToString(u))
1289
		}
1290
		return a, nil
1291
	case []float64:
1292
		for _, u := range v {
1293
			a = append(a, ToString(u))
1294
		}
1295
		return a, nil
1296
	case string:
1297
		return strings.Fields(v), nil
1298
	case []error:
1299
		for _, err := range i.([]error) {
1300
			a = append(a, err.Error())
1301
		}
1302
		return a, nil
1303
	case interface{}:
1304
		str, err := ToStringE(v)
1305
		if err != nil {
1306
			return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1307
		}
1308
		return []string{str}, nil
1309
	default:
1310
		return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1311
	}
1312
}
1313

1314
// ToIntSliceE casts an interface to a []int type.
1315
func ToIntSliceE(i interface{}) ([]int, error) {
1316
	if i == nil {
1317
		return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1318
	}
1319

1320
	switch v := i.(type) {
1321
	case []int:
1322
		return v, nil
1323
	}
1324

1325
	kind := reflect.TypeOf(i).Kind()
1326
	switch kind {
1327
	case reflect.Slice, reflect.Array:
1328
		s := reflect.ValueOf(i)
1329
		a := make([]int, s.Len())
1330
		for j := 0; j < s.Len(); j++ {
1331
			val, err := ToIntE(s.Index(j).Interface())
1332
			if err != nil {
1333
				return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1334
			}
1335
			a[j] = val
1336
		}
1337
		return a, nil
1338
	default:
1339
		return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1340
	}
1341
}
1342

1343
// ToDurationSliceE casts an interface to a []time.Duration type.
1344
func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
1345
	if i == nil {
1346
		return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1347
	}
1348

1349
	switch v := i.(type) {
1350
	case []time.Duration:
1351
		return v, nil
1352
	}
1353

1354
	kind := reflect.TypeOf(i).Kind()
1355
	switch kind {
1356
	case reflect.Slice, reflect.Array:
1357
		s := reflect.ValueOf(i)
1358
		a := make([]time.Duration, s.Len())
1359
		for j := 0; j < s.Len(); j++ {
1360
			val, err := ToDurationE(s.Index(j).Interface())
1361
			if err != nil {
1362
				return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1363
			}
1364
			a[j] = val
1365
		}
1366
		return a, nil
1367
	default:
1368
		return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1369
	}
1370
}
1371

1372
// StringToDate attempts to parse a string into a time.Time type using a
1373
// predefined list of formats.  If no suitable format is found, an error is
1374
// returned.
1375
func StringToDate(s string) (time.Time, error) {
1376
	return parseDateWith(s, time.UTC, timeFormats)
1377
}
1378

1379
// StringToDateInDefaultLocation casts an empty interface to a time.Time,
1380
// interpreting inputs without a timezone to be in the given location,
1381
// or the local timezone if nil.
1382
func StringToDateInDefaultLocation(s string, location *time.Location) (time.Time, error) {
1383
	return parseDateWith(s, location, timeFormats)
1384
}
1385

1386
type timeFormatType int
1387

1388
const (
1389
	timeFormatNoTimezone timeFormatType = iota
1390
	timeFormatNamedTimezone
1391
	timeFormatNumericTimezone
1392
	timeFormatNumericAndNamedTimezone
1393
	timeFormatTimeOnly
1394
)
1395

1396
type timeFormat struct {
1397
	format string
1398
	typ    timeFormatType
1399
}
1400

1401
func (f timeFormat) hasTimezone() bool {
1402
	// We don't include the formats with only named timezones, see
1403
	// https://github.com/golang/go/issues/19694#issuecomment-289103522
1404
	return f.typ >= timeFormatNumericTimezone && f.typ <= timeFormatNumericAndNamedTimezone
1405
}
1406

1407
var (
1408
	timeFormats = []timeFormat{
1409
		// Keep common formats at the top.
1410
		{"2006-01-02", timeFormatNoTimezone},
1411
		{time.RFC3339, timeFormatNumericTimezone},
1412
		{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
1413
		{time.RFC1123Z, timeFormatNumericTimezone},
1414
		{time.RFC1123, timeFormatNamedTimezone},
1415
		{time.RFC822Z, timeFormatNumericTimezone},
1416
		{time.RFC822, timeFormatNamedTimezone},
1417
		{time.RFC850, timeFormatNamedTimezone},
1418
		{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
1419
		{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone},                        // RFC3339 without timezone hh:mm colon
1420
		{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone},                        // RFC3339 without T or timezone hh:mm colon
1421
		{"2006-01-02 15:04:05", timeFormatNoTimezone},
1422
		{time.ANSIC, timeFormatNoTimezone},
1423
		{time.UnixDate, timeFormatNamedTimezone},
1424
		{time.RubyDate, timeFormatNumericTimezone},
1425
		{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
1426
		{"02 Jan 2006", timeFormatNoTimezone},
1427
		{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
1428
		{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
1429
		{time.Kitchen, timeFormatTimeOnly},
1430
		{time.Stamp, timeFormatTimeOnly},
1431
		{time.StampMilli, timeFormatTimeOnly},
1432
		{time.StampMicro, timeFormatTimeOnly},
1433
		{time.StampNano, timeFormatTimeOnly},
1434
	}
1435
)
1436

1437
func parseDateWith(s string, location *time.Location, formats []timeFormat) (d time.Time, e error) {
1438

1439
	for _, format := range formats {
1440
		if d, e = time.Parse(format.format, s); e == nil {
1441

1442
			// Some time formats have a zone name, but no offset, so it gets
1443
			// put in that zone name (not the default one passed in to us), but
1444
			// without that zone's offset. So set the location manually.
1445
			if format.typ <= timeFormatNamedTimezone {
1446
				if location == nil {
1447
					location = time.Local
1448
				}
1449
				year, month, day := d.Date()
1450
				hour, min, sec := d.Clock()
1451
				d = time.Date(year, month, day, hour, min, sec, d.Nanosecond(), location)
1452
			}
1453

1454
			return
1455
		}
1456
	}
1457
	return d, fmt.Errorf("unable to parse date: %s", s)
1458
}
1459

1460
// jsonStringToObject attempts to unmarshall a string as JSON into
1461
// the object passed as pointer.
1462
func jsonStringToObject(s string, v interface{}) error {
1463
	data := []byte(s)
1464
	return json.Unmarshal(data, v)
1465
}
1466

1467
// toInt returns the int value of v if v or v's underlying type
1468
// is an int.
1469
// Note that this will return false for int64 etc. types.
1470
func toInt(v interface{}) (int, bool) {
1471
	switch v := v.(type) {
1472
	case int:
1473
		return v, true
1474
	case time.Weekday:
1475
		return int(v), true
1476
	case time.Month:
1477
		return int(v), true
1478
	default:
1479
		return 0, false
1480
	}
1481
}
1482

1483
func trimZeroDecimal(s string) string {
1484
	var foundZero bool
1485
	for i := len(s); i > 0; i-- {
1486
		switch s[i-1] {
1487
		case '.':
1488
			if foundZero {
1489
				return s[:i-1]
1490
			}
1491
		case '0':
1492
			foundZero = true
1493
		default:
1494
			return s
1495
		}
1496
	}
1497
	return s
1498
}
1499

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.