github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/cast/caste.go (about)

     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  	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.
    48  func 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.
    74  func 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.
    95  func 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.
   140  func 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.
   185  func 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.
   232  func 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.
   279  func 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.
   326  func 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.
   373  func 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  		v, err := strconv.ParseInt(fmt.Sprintf("%v", i), 0, 0)
   416  		if err == nil {
   417  			return int(v), nil
   418  		}
   419  		return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
   420  	}
   421  }
   422  
   423  // ToUintE casts an interface to a uint type.
   424  func ToUintE(i interface{}) (uint, error) {
   425  	i = indirect(i)
   426  
   427  	switch s := i.(type) {
   428  	case string:
   429  		v, err := strconv.ParseUint(s, 0, 0)
   430  		if err == nil {
   431  			return uint(v), nil
   432  		}
   433  		return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
   434  	case int:
   435  		if s < 0 {
   436  			return 0, errNegativeNotAllowed
   437  		}
   438  		return uint(s), nil
   439  	case int64:
   440  		if s < 0 {
   441  			return 0, errNegativeNotAllowed
   442  		}
   443  		return uint(s), nil
   444  	case int32:
   445  		if s < 0 {
   446  			return 0, errNegativeNotAllowed
   447  		}
   448  		return uint(s), nil
   449  	case int16:
   450  		if s < 0 {
   451  			return 0, errNegativeNotAllowed
   452  		}
   453  		return uint(s), nil
   454  	case int8:
   455  		if s < 0 {
   456  			return 0, errNegativeNotAllowed
   457  		}
   458  		return uint(s), nil
   459  	case uint:
   460  		return s, nil
   461  	case uint64:
   462  		return uint(s), nil
   463  	case uint32:
   464  		return uint(s), nil
   465  	case uint16:
   466  		return uint(s), nil
   467  	case uint8:
   468  		return uint(s), nil
   469  	case float64:
   470  		if s < 0 {
   471  			return 0, errNegativeNotAllowed
   472  		}
   473  		return uint(s), nil
   474  	case float32:
   475  		if s < 0 {
   476  			return 0, errNegativeNotAllowed
   477  		}
   478  		return uint(s), nil
   479  	case bool:
   480  		if s {
   481  			return 1, nil
   482  		}
   483  		return 0, nil
   484  	case nil:
   485  		return 0, nil
   486  	default:
   487  		return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
   488  	}
   489  }
   490  
   491  // ToUint64E casts an interface to a uint64 type.
   492  func ToUint64E(i interface{}) (uint64, error) {
   493  	i = indirect(i)
   494  
   495  	switch s := i.(type) {
   496  	case string:
   497  		v, err := strconv.ParseUint(s, 0, 64)
   498  		if err == nil {
   499  			return v, nil
   500  		}
   501  		return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
   502  	case int:
   503  		if s < 0 {
   504  			return 0, errNegativeNotAllowed
   505  		}
   506  		return uint64(s), nil
   507  	case int64:
   508  		if s < 0 {
   509  			return 0, errNegativeNotAllowed
   510  		}
   511  		return uint64(s), nil
   512  	case int32:
   513  		if s < 0 {
   514  			return 0, errNegativeNotAllowed
   515  		}
   516  		return uint64(s), nil
   517  	case int16:
   518  		if s < 0 {
   519  			return 0, errNegativeNotAllowed
   520  		}
   521  		return uint64(s), nil
   522  	case int8:
   523  		if s < 0 {
   524  			return 0, errNegativeNotAllowed
   525  		}
   526  		return uint64(s), nil
   527  	case uint:
   528  		return uint64(s), nil
   529  	case uint64:
   530  		return s, nil
   531  	case uint32:
   532  		return uint64(s), nil
   533  	case uint16:
   534  		return uint64(s), nil
   535  	case uint8:
   536  		return uint64(s), nil
   537  	case float32:
   538  		if s < 0 {
   539  			return 0, errNegativeNotAllowed
   540  		}
   541  		return uint64(s), nil
   542  	case float64:
   543  		if s < 0 {
   544  			return 0, errNegativeNotAllowed
   545  		}
   546  		return uint64(s), nil
   547  	case bool:
   548  		if s {
   549  			return 1, nil
   550  		}
   551  		return 0, nil
   552  	case nil:
   553  		return 0, nil
   554  	default:
   555  		return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
   556  	}
   557  }
   558  
   559  // ToUint32E casts an interface to a uint32 type.
   560  func ToUint32E(i interface{}) (uint32, error) {
   561  	i = indirect(i)
   562  
   563  	switch s := i.(type) {
   564  	case string:
   565  		v, err := strconv.ParseUint(s, 0, 32)
   566  		if err == nil {
   567  			return uint32(v), nil
   568  		}
   569  		return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
   570  	case int:
   571  		if s < 0 {
   572  			return 0, errNegativeNotAllowed
   573  		}
   574  		return uint32(s), nil
   575  	case int64:
   576  		if s < 0 {
   577  			return 0, errNegativeNotAllowed
   578  		}
   579  		return uint32(s), nil
   580  	case int32:
   581  		if s < 0 {
   582  			return 0, errNegativeNotAllowed
   583  		}
   584  		return uint32(s), nil
   585  	case int16:
   586  		if s < 0 {
   587  			return 0, errNegativeNotAllowed
   588  		}
   589  		return uint32(s), nil
   590  	case int8:
   591  		if s < 0 {
   592  			return 0, errNegativeNotAllowed
   593  		}
   594  		return uint32(s), nil
   595  	case uint:
   596  		return uint32(s), nil
   597  	case uint64:
   598  		return uint32(s), nil
   599  	case uint32:
   600  		return s, nil
   601  	case uint16:
   602  		return uint32(s), nil
   603  	case uint8:
   604  		return uint32(s), nil
   605  	case float64:
   606  		if s < 0 {
   607  			return 0, errNegativeNotAllowed
   608  		}
   609  		return uint32(s), nil
   610  	case float32:
   611  		if s < 0 {
   612  			return 0, errNegativeNotAllowed
   613  		}
   614  		return uint32(s), nil
   615  	case bool:
   616  		if s {
   617  			return 1, nil
   618  		}
   619  		return 0, nil
   620  	case nil:
   621  		return 0, nil
   622  	default:
   623  		return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
   624  	}
   625  }
   626  
   627  // ToUint16E casts an interface to a uint16 type.
   628  func ToUint16E(i interface{}) (uint16, error) {
   629  	i = indirect(i)
   630  
   631  	switch s := i.(type) {
   632  	case string:
   633  		v, err := strconv.ParseUint(s, 0, 16)
   634  		if err == nil {
   635  			return uint16(v), nil
   636  		}
   637  		return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
   638  	case int:
   639  		if s < 0 {
   640  			return 0, errNegativeNotAllowed
   641  		}
   642  		return uint16(s), nil
   643  	case int64:
   644  		if s < 0 {
   645  			return 0, errNegativeNotAllowed
   646  		}
   647  		return uint16(s), nil
   648  	case int32:
   649  		if s < 0 {
   650  			return 0, errNegativeNotAllowed
   651  		}
   652  		return uint16(s), nil
   653  	case int16:
   654  		if s < 0 {
   655  			return 0, errNegativeNotAllowed
   656  		}
   657  		return uint16(s), nil
   658  	case int8:
   659  		if s < 0 {
   660  			return 0, errNegativeNotAllowed
   661  		}
   662  		return uint16(s), nil
   663  	case uint:
   664  		return uint16(s), nil
   665  	case uint64:
   666  		return uint16(s), nil
   667  	case uint32:
   668  		return uint16(s), nil
   669  	case uint16:
   670  		return s, nil
   671  	case uint8:
   672  		return uint16(s), nil
   673  	case float64:
   674  		if s < 0 {
   675  			return 0, errNegativeNotAllowed
   676  		}
   677  		return uint16(s), nil
   678  	case float32:
   679  		if s < 0 {
   680  			return 0, errNegativeNotAllowed
   681  		}
   682  		return uint16(s), nil
   683  	case bool:
   684  		if s {
   685  			return 1, nil
   686  		}
   687  		return 0, nil
   688  	case nil:
   689  		return 0, nil
   690  	default:
   691  		return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
   692  	}
   693  }
   694  
   695  // ToUint8E casts an interface to a uint type.
   696  func ToUint8E(i interface{}) (uint8, error) {
   697  	i = indirect(i)
   698  
   699  	switch s := i.(type) {
   700  	case string:
   701  		v, err := strconv.ParseUint(s, 0, 8)
   702  		if err == nil {
   703  			return uint8(v), nil
   704  		}
   705  		return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
   706  	case int:
   707  		if s < 0 {
   708  			return 0, errNegativeNotAllowed
   709  		}
   710  		return uint8(s), nil
   711  	case int64:
   712  		if s < 0 {
   713  			return 0, errNegativeNotAllowed
   714  		}
   715  		return uint8(s), nil
   716  	case int32:
   717  		if s < 0 {
   718  			return 0, errNegativeNotAllowed
   719  		}
   720  		return uint8(s), nil
   721  	case int16:
   722  		if s < 0 {
   723  			return 0, errNegativeNotAllowed
   724  		}
   725  		return uint8(s), nil
   726  	case int8:
   727  		if s < 0 {
   728  			return 0, errNegativeNotAllowed
   729  		}
   730  		return uint8(s), nil
   731  	case uint:
   732  		return uint8(s), nil
   733  	case uint64:
   734  		return uint8(s), nil
   735  	case uint32:
   736  		return uint8(s), nil
   737  	case uint16:
   738  		return uint8(s), nil
   739  	case uint8:
   740  		return s, nil
   741  	case float64:
   742  		if s < 0 {
   743  			return 0, errNegativeNotAllowed
   744  		}
   745  		return uint8(s), nil
   746  	case float32:
   747  		if s < 0 {
   748  			return 0, errNegativeNotAllowed
   749  		}
   750  		return uint8(s), nil
   751  	case bool:
   752  		if s {
   753  			return 1, nil
   754  		}
   755  		return 0, nil
   756  	case nil:
   757  		return 0, nil
   758  	default:
   759  		return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
   760  	}
   761  }
   762  
   763  // From html/template/content.go
   764  // Copyright 2011 The Go Authors. All rights reserved.
   765  // indirect returns the value, after dereferencing as many times
   766  // as necessary to reach the base type (or nil).
   767  func indirect(a interface{}) interface{} {
   768  	if a == nil {
   769  		return nil
   770  	}
   771  	if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
   772  		// Avoid creating a reflect.Value if it's not a pointer.
   773  		return a
   774  	}
   775  	v := reflect.ValueOf(a)
   776  	for v.Kind() == reflect.Ptr && !v.IsNil() {
   777  		v = v.Elem()
   778  	}
   779  	return v.Interface()
   780  }
   781  
   782  // From html/template/content.go
   783  // Copyright 2011 The Go Authors. All rights reserved.
   784  // indirectToStringerOrError returns the value, after dereferencing as many times
   785  // as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
   786  // or error,
   787  func indirectToStringerOrError(a interface{}) interface{} {
   788  	if a == nil {
   789  		return nil
   790  	}
   791  
   792  	errorType := reflect.TypeOf((*error)(nil)).Elem()
   793  	fmtStringerType := reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
   794  
   795  	v := reflect.ValueOf(a)
   796  	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
   797  		v = v.Elem()
   798  	}
   799  	return v.Interface()
   800  }
   801  
   802  // ToStringE casts an interface to a string type.
   803  func ToStringE(i interface{}) (string, error) {
   804  	i = indirectToStringerOrError(i)
   805  
   806  	switch s := i.(type) {
   807  	case string:
   808  		return s, nil
   809  	case bool:
   810  		return strconv.FormatBool(s), nil
   811  	case float64:
   812  		return strconv.FormatFloat(s, 'f', -1, 64), nil
   813  	case float32:
   814  		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
   815  	case int:
   816  		return strconv.Itoa(s), nil
   817  	case int64:
   818  		return strconv.FormatInt(s, 10), nil
   819  	case int32:
   820  		return strconv.Itoa(int(s)), nil
   821  	case int16:
   822  		return strconv.FormatInt(int64(s), 10), nil
   823  	case int8:
   824  		return strconv.FormatInt(int64(s), 10), nil
   825  	case uint:
   826  		return strconv.FormatUint(uint64(s), 10), nil
   827  	case uint64:
   828  		return strconv.FormatUint(uint64(s), 10), nil
   829  	case uint32:
   830  		return strconv.FormatUint(uint64(s), 10), nil
   831  	case uint16:
   832  		return strconv.FormatUint(uint64(s), 10), nil
   833  	case uint8:
   834  		return strconv.FormatUint(uint64(s), 10), nil
   835  	case []byte:
   836  		return string(s), nil
   837  	case template.HTML:
   838  		return string(s), nil
   839  	case template.URL:
   840  		return string(s), nil
   841  	case template.JS:
   842  		return string(s), nil
   843  	case template.CSS:
   844  		return string(s), nil
   845  	case template.HTMLAttr:
   846  		return string(s), nil
   847  	case nil:
   848  		return "", nil
   849  	case fmt.Stringer:
   850  		return s.String(), nil
   851  	case error:
   852  		return s.Error(), nil
   853  	default:
   854  		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
   855  	}
   856  }
   857  
   858  // ToStringMapStringE casts an interface to a map[string]string type.
   859  func ToStringMapStringE(i interface{}) (map[string]string, error) {
   860  	m := map[string]string{}
   861  
   862  	switch v := i.(type) {
   863  	case map[string]string:
   864  		return v, nil
   865  	case map[string]interface{}:
   866  		for k, val := range v {
   867  			m[ToString(k)] = ToString(val)
   868  		}
   869  		return m, nil
   870  	case map[interface{}]string:
   871  		for k, val := range v {
   872  			m[ToString(k)] = ToString(val)
   873  		}
   874  		return m, nil
   875  	case map[interface{}]interface{}:
   876  		for k, val := range v {
   877  			m[ToString(k)] = ToString(val)
   878  		}
   879  		return m, nil
   880  	case string:
   881  		err := jsonStringToObject(v, &m)
   882  		return m, err
   883  	default:
   884  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
   885  	}
   886  }
   887  
   888  // ToStringMapStringSliceE casts an interface to a map[string][]string type.
   889  func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
   890  	m := map[string][]string{}
   891  
   892  	switch v := i.(type) {
   893  	case map[string][]string:
   894  		return v, nil
   895  	case map[string][]interface{}:
   896  		for k, val := range v {
   897  			m[ToString(k)] = ToStringSlice(val)
   898  		}
   899  		return m, nil
   900  	case map[string]string:
   901  		for k, val := range v {
   902  			m[ToString(k)] = []string{val}
   903  		}
   904  	case map[string]interface{}:
   905  		for k, val := range v {
   906  			switch vt := val.(type) {
   907  			case []interface{}:
   908  				m[ToString(k)] = ToStringSlice(vt)
   909  			case []string:
   910  				m[ToString(k)] = vt
   911  			default:
   912  				m[ToString(k)] = []string{ToString(val)}
   913  			}
   914  		}
   915  		return m, nil
   916  	case map[interface{}][]string:
   917  		for k, val := range v {
   918  			m[ToString(k)] = ToStringSlice(val)
   919  		}
   920  		return m, nil
   921  	case map[interface{}]string:
   922  		for k, val := range v {
   923  			m[ToString(k)] = ToStringSlice(val)
   924  		}
   925  		return m, nil
   926  	case map[interface{}][]interface{}:
   927  		for k, val := range v {
   928  			m[ToString(k)] = ToStringSlice(val)
   929  		}
   930  		return m, nil
   931  	case map[interface{}]interface{}:
   932  		for k, val := range v {
   933  			key, err := ToStringE(k)
   934  			if err != nil {
   935  				return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
   936  			}
   937  			value, err := ToStringSliceE(val)
   938  			if err != nil {
   939  				return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
   940  			}
   941  			m[key] = value
   942  		}
   943  	case string:
   944  		err := jsonStringToObject(v, &m)
   945  		return m, err
   946  	default:
   947  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
   948  	}
   949  	return m, nil
   950  }
   951  
   952  // ToStringMapBoolE casts an interface to a map[string]bool type.
   953  func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
   954  	m := map[string]bool{}
   955  
   956  	switch v := i.(type) {
   957  	case map[interface{}]interface{}:
   958  		for k, val := range v {
   959  			m[ToString(k)] = ToBool(val)
   960  		}
   961  		return m, nil
   962  	case map[string]interface{}:
   963  		for k, val := range v {
   964  			m[ToString(k)] = ToBool(val)
   965  		}
   966  		return m, nil
   967  	case map[string]bool:
   968  		return v, nil
   969  	case string:
   970  		err := jsonStringToObject(v, &m)
   971  		return m, err
   972  	default:
   973  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
   974  	}
   975  }
   976  
   977  // ToStringMapE casts an interface to a map[string]interface{} type.
   978  func ToStringMapE(i interface{}) (map[string]interface{}, error) {
   979  	m := map[string]interface{}{}
   980  
   981  	switch v := i.(type) {
   982  	case map[interface{}]interface{}:
   983  		for k, val := range v {
   984  			m[ToString(k)] = val
   985  		}
   986  		return m, nil
   987  	case map[string]interface{}:
   988  		return v, nil
   989  	case string:
   990  		err := jsonStringToObject(v, &m)
   991  		return m, err
   992  	default:
   993  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
   994  	}
   995  }
   996  
   997  // ToStringMapIntE casts an interface to a map[string]int{} type.
   998  func ToStringMapIntE(i interface{}) (map[string]int, error) {
   999  	m := map[string]int{}
  1000  	if i == nil {
  1001  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
  1002  	}
  1003  
  1004  	switch v := i.(type) {
  1005  	case map[interface{}]interface{}:
  1006  		for k, val := range v {
  1007  			m[ToString(k)] = ToInt(val)
  1008  		}
  1009  		return m, nil
  1010  	case map[string]interface{}:
  1011  		for k, val := range v {
  1012  			m[k] = ToInt(val)
  1013  		}
  1014  		return m, nil
  1015  	case map[string]int:
  1016  		return v, nil
  1017  	case string:
  1018  		err := jsonStringToObject(v, &m)
  1019  		return m, err
  1020  	}
  1021  
  1022  	if reflect.TypeOf(i).Kind() != reflect.Map {
  1023  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
  1024  	}
  1025  
  1026  	mVal := reflect.ValueOf(m)
  1027  	v := reflect.ValueOf(i)
  1028  	for _, keyVal := range v.MapKeys() {
  1029  		val, err := ToIntE(v.MapIndex(keyVal).Interface())
  1030  		if err != nil {
  1031  			return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
  1032  		}
  1033  		mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
  1034  	}
  1035  	return m, nil
  1036  }
  1037  
  1038  // ToStringMapInt64E casts an interface to a map[string]int64{} type.
  1039  func ToStringMapInt64E(i interface{}) (map[string]int64, error) {
  1040  	m := map[string]int64{}
  1041  	if i == nil {
  1042  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
  1043  	}
  1044  
  1045  	switch v := i.(type) {
  1046  	case map[interface{}]interface{}:
  1047  		for k, val := range v {
  1048  			m[ToString(k)] = ToInt64(val)
  1049  		}
  1050  		return m, nil
  1051  	case map[string]interface{}:
  1052  		for k, val := range v {
  1053  			m[k] = ToInt64(val)
  1054  		}
  1055  		return m, nil
  1056  	case map[string]int64:
  1057  		return v, nil
  1058  	case string:
  1059  		err := jsonStringToObject(v, &m)
  1060  		return m, err
  1061  	}
  1062  
  1063  	if reflect.TypeOf(i).Kind() != reflect.Map {
  1064  		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
  1065  	}
  1066  	mVal := reflect.ValueOf(m)
  1067  	v := reflect.ValueOf(i)
  1068  	for _, keyVal := range v.MapKeys() {
  1069  		val, err := ToInt64E(v.MapIndex(keyVal).Interface())
  1070  		if err != nil {
  1071  			return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
  1072  		}
  1073  		mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
  1074  	}
  1075  	return m, nil
  1076  }
  1077  
  1078  // ToSliceE casts an interface to a []interface{} type.
  1079  func ToSliceE(i interface{}) ([]interface{}, error) {
  1080  	var s []interface{}
  1081  
  1082  	switch v := i.(type) {
  1083  	case []interface{}:
  1084  		return append(s, v...), nil
  1085  	case []map[string]interface{}:
  1086  		for _, u := range v {
  1087  			s = append(s, u)
  1088  		}
  1089  		return s, nil
  1090  	default:
  1091  		return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
  1092  	}
  1093  }
  1094  
  1095  // ToBoolSliceE casts an interface to a []bool type.
  1096  func ToBoolSliceE(i interface{}) ([]bool, error) {
  1097  	if i == nil {
  1098  		return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
  1099  	}
  1100  
  1101  	switch v := i.(type) {
  1102  	case []bool:
  1103  		return v, nil
  1104  	}
  1105  
  1106  	kind := reflect.TypeOf(i).Kind()
  1107  	switch kind {
  1108  	case reflect.Slice, reflect.Array:
  1109  		s := reflect.ValueOf(i)
  1110  		a := make([]bool, s.Len())
  1111  		for j := 0; j < s.Len(); j++ {
  1112  			val, err := ToBoolE(s.Index(j).Interface())
  1113  			if err != nil {
  1114  				return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
  1115  			}
  1116  			a[j] = val
  1117  		}
  1118  		return a, nil
  1119  	default:
  1120  		return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
  1121  	}
  1122  }
  1123  
  1124  // ToStringSliceE casts an interface to a []string type.
  1125  func ToStringSliceE(i interface{}) ([]string, error) {
  1126  	var a []string
  1127  
  1128  	switch v := i.(type) {
  1129  	case []interface{}:
  1130  		for _, u := range v {
  1131  			a = append(a, ToString(u))
  1132  		}
  1133  		return a, nil
  1134  	case []string:
  1135  		return v, nil
  1136  	case []int8:
  1137  		for _, u := range v {
  1138  			a = append(a, ToString(u))
  1139  		}
  1140  		return a, nil
  1141  	case []int:
  1142  		for _, u := range v {
  1143  			a = append(a, ToString(u))
  1144  		}
  1145  		return a, nil
  1146  	case []int32:
  1147  		for _, u := range v {
  1148  			a = append(a, ToString(u))
  1149  		}
  1150  		return a, nil
  1151  	case []int64:
  1152  		for _, u := range v {
  1153  			a = append(a, ToString(u))
  1154  		}
  1155  		return a, nil
  1156  	case []float32:
  1157  		for _, u := range v {
  1158  			a = append(a, ToString(u))
  1159  		}
  1160  		return a, nil
  1161  	case []float64:
  1162  		for _, u := range v {
  1163  			a = append(a, ToString(u))
  1164  		}
  1165  		return a, nil
  1166  	case string:
  1167  		return strings.Fields(v), nil
  1168  	case []error:
  1169  		for _, err := range i.([]error) {
  1170  			a = append(a, err.Error())
  1171  		}
  1172  		return a, nil
  1173  	case interface{}:
  1174  		str, err := ToStringE(v)
  1175  		if err != nil {
  1176  			return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
  1177  		}
  1178  		return []string{str}, nil
  1179  	default:
  1180  		return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
  1181  	}
  1182  }
  1183  
  1184  // ToIntSliceE casts an interface to a []int type.
  1185  func ToIntSliceE(i interface{}) ([]int, error) {
  1186  	if i == nil {
  1187  		return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
  1188  	}
  1189  
  1190  	switch v := i.(type) {
  1191  	case []int:
  1192  		return v, nil
  1193  	}
  1194  
  1195  	kind := reflect.TypeOf(i).Kind()
  1196  	switch kind {
  1197  	case reflect.Slice, reflect.Array:
  1198  		s := reflect.ValueOf(i)
  1199  		a := make([]int, s.Len())
  1200  		for j := 0; j < s.Len(); j++ {
  1201  			val, err := ToIntE(s.Index(j).Interface())
  1202  			if err != nil {
  1203  				return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
  1204  			}
  1205  			a[j] = val
  1206  		}
  1207  		return a, nil
  1208  	default:
  1209  		return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
  1210  	}
  1211  }
  1212  
  1213  // ToDurationSliceE casts an interface to a []time.Duration type.
  1214  func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
  1215  	if i == nil {
  1216  		return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
  1217  	}
  1218  
  1219  	switch v := i.(type) {
  1220  	case []time.Duration:
  1221  		return v, nil
  1222  	}
  1223  
  1224  	kind := reflect.TypeOf(i).Kind()
  1225  	switch kind {
  1226  	case reflect.Slice, reflect.Array:
  1227  		s := reflect.ValueOf(i)
  1228  		a := make([]time.Duration, s.Len())
  1229  		for j := 0; j < s.Len(); j++ {
  1230  			val, err := ToDurationE(s.Index(j).Interface())
  1231  			if err != nil {
  1232  				return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
  1233  			}
  1234  			a[j] = val
  1235  		}
  1236  		return a, nil
  1237  	default:
  1238  		return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
  1239  	}
  1240  }
  1241  
  1242  // StringToDate attempts to parse a string into a time.Time type using a
  1243  // predefined list of formats.  If no suitable format is found, an error is
  1244  // returned.
  1245  func StringToDate(s string) (time.Time, error) {
  1246  	return parseDateWith(s, []string{
  1247  		time.RFC3339,
  1248  		"2006-01-02T15:04:05", // iso8601 without timezone
  1249  		time.RFC1123Z,
  1250  		time.RFC1123,
  1251  		time.RFC822Z,
  1252  		time.RFC822,
  1253  		time.RFC850,
  1254  		time.ANSIC,
  1255  		time.UnixDate,
  1256  		time.RubyDate,
  1257  		"2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
  1258  		"2006-01-02",
  1259  		"02 Jan 2006",
  1260  		"2006-01-02T15:04:05-0700", // RFC3339 without timezone hh:mm colon
  1261  		"2006-01-02 15:04:05 -07:00",
  1262  		"2006-01-02 15:04:05 -0700",
  1263  		"2006-01-02 15:04:05Z07:00", // RFC3339 without T
  1264  		"2006-01-02 15:04:05Z0700",  // RFC3339 without T or timezone hh:mm colon
  1265  		"2006-01-02 15:04:05",
  1266  		time.Kitchen,
  1267  		time.Stamp,
  1268  		time.StampMilli,
  1269  		time.StampMicro,
  1270  		time.StampNano,
  1271  	})
  1272  }
  1273  
  1274  func parseDateWith(s string, dates []string) (d time.Time, e error) {
  1275  	for _, dateType := range dates {
  1276  		if d, e = time.Parse(dateType, s); e == nil {
  1277  			return
  1278  		}
  1279  	}
  1280  	return d, fmt.Errorf("unable to parse date: %s", s)
  1281  }
  1282  
  1283  // jsonStringToObject attempts to unmarshall a string as JSON into
  1284  // the object passed as pointer.
  1285  func jsonStringToObject(s string, v interface{}) error {
  1286  	data := []byte(s)
  1287  	return json.Unmarshal(data, v)
  1288  }