github.com/chain5j/chain5j-pkg@v1.0.7/util/convutil/caste.go (about)

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