caste.go (33547B)
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 }