caste.go raw

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