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