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