vendor/github.com/spf13/cast/caste.go
changeset 260 445e01aede7e
parent 251 1c52a0eeb952
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
    18 
    18 
    19 var errNegativeNotAllowed = errors.New("unable to cast negative value")
    19 var errNegativeNotAllowed = errors.New("unable to cast negative value")
    20 
    20 
    21 // ToTimeE casts an interface to a time.Time type.
    21 // ToTimeE casts an interface to a time.Time type.
    22 func ToTimeE(i interface{}) (tim time.Time, err error) {
    22 func ToTimeE(i interface{}) (tim time.Time, err error) {
       
    23 	return ToTimeInDefaultLocationE(i, time.UTC)
       
    24 }
       
    25 
       
    26 // ToTimeInDefaultLocationE casts an empty interface to time.Time,
       
    27 // interpreting inputs without a timezone to be in the given location,
       
    28 // or the local timezone if nil.
       
    29 func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.Time, err error) {
    23 	i = indirect(i)
    30 	i = indirect(i)
    24 
    31 
    25 	switch v := i.(type) {
    32 	switch v := i.(type) {
    26 	case time.Time:
    33 	case time.Time:
    27 		return v, nil
    34 		return v, nil
    28 	case string:
    35 	case string:
    29 		return StringToDate(v)
    36 		return StringToDateInDefaultLocation(v, location)
       
    37 	case json.Number:
       
    38 		s, err1 := ToInt64E(v)
       
    39 		if err1 != nil {
       
    40 			return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
       
    41 		}
       
    42 		return time.Unix(s, 0), nil
    30 	case int:
    43 	case int:
    31 		return time.Unix(int64(v), 0), nil
    44 		return time.Unix(int64(v), 0), nil
    32 	case int64:
    45 	case int64:
    33 		return time.Unix(v, 0), nil
    46 		return time.Unix(v, 0), nil
    34 	case int32:
    47 	case int32:
    62 			d, err = time.ParseDuration(s)
    75 			d, err = time.ParseDuration(s)
    63 		} else {
    76 		} else {
    64 			d, err = time.ParseDuration(s + "ns")
    77 			d, err = time.ParseDuration(s + "ns")
    65 		}
    78 		}
    66 		return
    79 		return
       
    80 	case json.Number:
       
    81 		var v float64
       
    82 		v, err = s.Float64()
       
    83 		d = time.Duration(v)
       
    84 		return
    67 	default:
    85 	default:
    68 		err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
    86 		err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
    69 		return
    87 		return
    70 	}
    88 	}
    71 }
    89 }
    84 			return true, nil
   102 			return true, nil
    85 		}
   103 		}
    86 		return false, nil
   104 		return false, nil
    87 	case string:
   105 	case string:
    88 		return strconv.ParseBool(i.(string))
   106 		return strconv.ParseBool(i.(string))
       
   107 	case json.Number:
       
   108 		v, err := ToInt64E(b)
       
   109 		if err == nil {
       
   110 			return v != 0, nil
       
   111 		}
       
   112 		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
    89 	default:
   113 	default:
    90 		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
   114 		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
    91 	}
   115 	}
    92 }
   116 }
    93 
   117 
    94 // ToFloat64E casts an interface to a float64 type.
   118 // ToFloat64E casts an interface to a float64 type.
    95 func ToFloat64E(i interface{}) (float64, error) {
   119 func ToFloat64E(i interface{}) (float64, error) {
    96 	i = indirect(i)
   120 	i = indirect(i)
       
   121 
       
   122 	intv, ok := toInt(i)
       
   123 	if ok {
       
   124 		return float64(intv), nil
       
   125 	}
    97 
   126 
    98 	switch s := i.(type) {
   127 	switch s := i.(type) {
    99 	case float64:
   128 	case float64:
   100 		return s, nil
   129 		return s, nil
   101 	case float32:
   130 	case float32:
   102 		return float64(s), nil
       
   103 	case int:
       
   104 		return float64(s), nil
   131 		return float64(s), nil
   105 	case int64:
   132 	case int64:
   106 		return float64(s), nil
   133 		return float64(s), nil
   107 	case int32:
   134 	case int32:
   108 		return float64(s), nil
   135 		return float64(s), nil
   124 		v, err := strconv.ParseFloat(s, 64)
   151 		v, err := strconv.ParseFloat(s, 64)
   125 		if err == nil {
   152 		if err == nil {
   126 			return v, nil
   153 			return v, nil
   127 		}
   154 		}
   128 		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
   155 		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
       
   156 	case json.Number:
       
   157 		v, err := s.Float64()
       
   158 		if err == nil {
       
   159 			return v, nil
       
   160 		}
       
   161 		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
   129 	case bool:
   162 	case bool:
   130 		if s {
   163 		if s {
   131 			return 1, nil
   164 			return 1, nil
   132 		}
   165 		}
   133 		return 0, nil
   166 		return 0, nil
       
   167 	case nil:
       
   168 		return 0, nil
   134 	default:
   169 	default:
   135 		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
   170 		return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
   136 	}
   171 	}
   137 }
   172 }
   138 
   173 
   139 // ToFloat32E casts an interface to a float32 type.
   174 // ToFloat32E casts an interface to a float32 type.
   140 func ToFloat32E(i interface{}) (float32, error) {
   175 func ToFloat32E(i interface{}) (float32, error) {
   141 	i = indirect(i)
   176 	i = indirect(i)
       
   177 
       
   178 	intv, ok := toInt(i)
       
   179 	if ok {
       
   180 		return float32(intv), nil
       
   181 	}
   142 
   182 
   143 	switch s := i.(type) {
   183 	switch s := i.(type) {
   144 	case float64:
   184 	case float64:
   145 		return float32(s), nil
   185 		return float32(s), nil
   146 	case float32:
   186 	case float32:
   147 		return s, nil
   187 		return s, nil
   148 	case int:
       
   149 		return float32(s), nil
       
   150 	case int64:
   188 	case int64:
   151 		return float32(s), nil
   189 		return float32(s), nil
   152 	case int32:
   190 	case int32:
   153 		return float32(s), nil
   191 		return float32(s), nil
   154 	case int16:
   192 	case int16:
   169 		v, err := strconv.ParseFloat(s, 32)
   207 		v, err := strconv.ParseFloat(s, 32)
   170 		if err == nil {
   208 		if err == nil {
   171 			return float32(v), nil
   209 			return float32(v), nil
   172 		}
   210 		}
   173 		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
   211 		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
       
   212 	case json.Number:
       
   213 		v, err := s.Float64()
       
   214 		if err == nil {
       
   215 			return float32(v), nil
       
   216 		}
       
   217 		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
   174 	case bool:
   218 	case bool:
   175 		if s {
   219 		if s {
   176 			return 1, nil
   220 			return 1, nil
   177 		}
   221 		}
   178 		return 0, nil
   222 		return 0, nil
       
   223 	case nil:
       
   224 		return 0, nil
   179 	default:
   225 	default:
   180 		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
   226 		return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
   181 	}
   227 	}
   182 }
   228 }
   183 
   229 
   184 // ToInt64E casts an interface to an int64 type.
   230 // ToInt64E casts an interface to an int64 type.
   185 func ToInt64E(i interface{}) (int64, error) {
   231 func ToInt64E(i interface{}) (int64, error) {
   186 	i = indirect(i)
   232 	i = indirect(i)
   187 
   233 
       
   234 	intv, ok := toInt(i)
       
   235 	if ok {
       
   236 		return int64(intv), nil
       
   237 	}
       
   238 
   188 	switch s := i.(type) {
   239 	switch s := i.(type) {
   189 	case int:
       
   190 		return int64(s), nil
       
   191 	case int64:
   240 	case int64:
   192 		return s, nil
   241 		return s, nil
   193 	case int32:
   242 	case int32:
   194 		return int64(s), nil
   243 		return int64(s), nil
   195 	case int16:
   244 	case int16:
   209 	case float64:
   258 	case float64:
   210 		return int64(s), nil
   259 		return int64(s), nil
   211 	case float32:
   260 	case float32:
   212 		return int64(s), nil
   261 		return int64(s), nil
   213 	case string:
   262 	case string:
   214 		v, err := strconv.ParseInt(s, 0, 0)
   263 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   215 		if err == nil {
   264 		if err == nil {
   216 			return v, nil
   265 			return v, nil
   217 		}
   266 		}
   218 		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
   267 		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
       
   268 	case json.Number:
       
   269 		return ToInt64E(string(s))
   219 	case bool:
   270 	case bool:
   220 		if s {
   271 		if s {
   221 			return 1, nil
   272 			return 1, nil
   222 		}
   273 		}
   223 		return 0, nil
   274 		return 0, nil
   230 
   281 
   231 // ToInt32E casts an interface to an int32 type.
   282 // ToInt32E casts an interface to an int32 type.
   232 func ToInt32E(i interface{}) (int32, error) {
   283 func ToInt32E(i interface{}) (int32, error) {
   233 	i = indirect(i)
   284 	i = indirect(i)
   234 
   285 
       
   286 	intv, ok := toInt(i)
       
   287 	if ok {
       
   288 		return int32(intv), nil
       
   289 	}
       
   290 
   235 	switch s := i.(type) {
   291 	switch s := i.(type) {
   236 	case int:
       
   237 		return int32(s), nil
       
   238 	case int64:
   292 	case int64:
   239 		return int32(s), nil
   293 		return int32(s), nil
   240 	case int32:
   294 	case int32:
   241 		return s, nil
   295 		return s, nil
   242 	case int16:
   296 	case int16:
   256 	case float64:
   310 	case float64:
   257 		return int32(s), nil
   311 		return int32(s), nil
   258 	case float32:
   312 	case float32:
   259 		return int32(s), nil
   313 		return int32(s), nil
   260 	case string:
   314 	case string:
   261 		v, err := strconv.ParseInt(s, 0, 0)
   315 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   262 		if err == nil {
   316 		if err == nil {
   263 			return int32(v), nil
   317 			return int32(v), nil
   264 		}
   318 		}
   265 		return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
   319 		return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
       
   320 	case json.Number:
       
   321 		return ToInt32E(string(s))
   266 	case bool:
   322 	case bool:
   267 		if s {
   323 		if s {
   268 			return 1, nil
   324 			return 1, nil
   269 		}
   325 		}
   270 		return 0, nil
   326 		return 0, nil
   277 
   333 
   278 // ToInt16E casts an interface to an int16 type.
   334 // ToInt16E casts an interface to an int16 type.
   279 func ToInt16E(i interface{}) (int16, error) {
   335 func ToInt16E(i interface{}) (int16, error) {
   280 	i = indirect(i)
   336 	i = indirect(i)
   281 
   337 
       
   338 	intv, ok := toInt(i)
       
   339 	if ok {
       
   340 		return int16(intv), nil
       
   341 	}
       
   342 
   282 	switch s := i.(type) {
   343 	switch s := i.(type) {
   283 	case int:
       
   284 		return int16(s), nil
       
   285 	case int64:
   344 	case int64:
   286 		return int16(s), nil
   345 		return int16(s), nil
   287 	case int32:
   346 	case int32:
   288 		return int16(s), nil
   347 		return int16(s), nil
   289 	case int16:
   348 	case int16:
   303 	case float64:
   362 	case float64:
   304 		return int16(s), nil
   363 		return int16(s), nil
   305 	case float32:
   364 	case float32:
   306 		return int16(s), nil
   365 		return int16(s), nil
   307 	case string:
   366 	case string:
   308 		v, err := strconv.ParseInt(s, 0, 0)
   367 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   309 		if err == nil {
   368 		if err == nil {
   310 			return int16(v), nil
   369 			return int16(v), nil
   311 		}
   370 		}
   312 		return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
   371 		return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
       
   372 	case json.Number:
       
   373 		return ToInt16E(string(s))
   313 	case bool:
   374 	case bool:
   314 		if s {
   375 		if s {
   315 			return 1, nil
   376 			return 1, nil
   316 		}
   377 		}
   317 		return 0, nil
   378 		return 0, nil
   324 
   385 
   325 // ToInt8E casts an interface to an int8 type.
   386 // ToInt8E casts an interface to an int8 type.
   326 func ToInt8E(i interface{}) (int8, error) {
   387 func ToInt8E(i interface{}) (int8, error) {
   327 	i = indirect(i)
   388 	i = indirect(i)
   328 
   389 
       
   390 	intv, ok := toInt(i)
       
   391 	if ok {
       
   392 		return int8(intv), nil
       
   393 	}
       
   394 
   329 	switch s := i.(type) {
   395 	switch s := i.(type) {
   330 	case int:
       
   331 		return int8(s), nil
       
   332 	case int64:
   396 	case int64:
   333 		return int8(s), nil
   397 		return int8(s), nil
   334 	case int32:
   398 	case int32:
   335 		return int8(s), nil
   399 		return int8(s), nil
   336 	case int16:
   400 	case int16:
   350 	case float64:
   414 	case float64:
   351 		return int8(s), nil
   415 		return int8(s), nil
   352 	case float32:
   416 	case float32:
   353 		return int8(s), nil
   417 		return int8(s), nil
   354 	case string:
   418 	case string:
   355 		v, err := strconv.ParseInt(s, 0, 0)
   419 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   356 		if err == nil {
   420 		if err == nil {
   357 			return int8(v), nil
   421 			return int8(v), nil
   358 		}
   422 		}
   359 		return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
   423 		return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
       
   424 	case json.Number:
       
   425 		return ToInt8E(string(s))
   360 	case bool:
   426 	case bool:
   361 		if s {
   427 		if s {
   362 			return 1, nil
   428 			return 1, nil
   363 		}
   429 		}
   364 		return 0, nil
   430 		return 0, nil
   371 
   437 
   372 // ToIntE casts an interface to an int type.
   438 // ToIntE casts an interface to an int type.
   373 func ToIntE(i interface{}) (int, error) {
   439 func ToIntE(i interface{}) (int, error) {
   374 	i = indirect(i)
   440 	i = indirect(i)
   375 
   441 
       
   442 	intv, ok := toInt(i)
       
   443 	if ok {
       
   444 		return intv, nil
       
   445 	}
       
   446 
   376 	switch s := i.(type) {
   447 	switch s := i.(type) {
   377 	case int:
       
   378 		return s, nil
       
   379 	case int64:
   448 	case int64:
   380 		return int(s), nil
   449 		return int(s), nil
   381 	case int32:
   450 	case int32:
   382 		return int(s), nil
   451 		return int(s), nil
   383 	case int16:
   452 	case int16:
   397 	case float64:
   466 	case float64:
   398 		return int(s), nil
   467 		return int(s), nil
   399 	case float32:
   468 	case float32:
   400 		return int(s), nil
   469 		return int(s), nil
   401 	case string:
   470 	case string:
   402 		v, err := strconv.ParseInt(s, 0, 0)
   471 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   403 		if err == nil {
   472 		if err == nil {
   404 			return int(v), nil
   473 			return int(v), nil
   405 		}
   474 		}
   406 		return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
   475 		return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
       
   476 	case json.Number:
       
   477 		return ToIntE(string(s))
   407 	case bool:
   478 	case bool:
   408 		if s {
   479 		if s {
   409 			return 1, nil
   480 			return 1, nil
   410 		}
   481 		}
   411 		return 0, nil
   482 		return 0, nil
   418 
   489 
   419 // ToUintE casts an interface to a uint type.
   490 // ToUintE casts an interface to a uint type.
   420 func ToUintE(i interface{}) (uint, error) {
   491 func ToUintE(i interface{}) (uint, error) {
   421 	i = indirect(i)
   492 	i = indirect(i)
   422 
   493 
       
   494 	intv, ok := toInt(i)
       
   495 	if ok {
       
   496 		if intv < 0 {
       
   497 			return 0, errNegativeNotAllowed
       
   498 		}
       
   499 		return uint(intv), nil
       
   500 	}
       
   501 
   423 	switch s := i.(type) {
   502 	switch s := i.(type) {
   424 	case string:
   503 	case string:
   425 		v, err := strconv.ParseUint(s, 0, 0)
   504 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   426 		if err == nil {
   505 		if err == nil {
       
   506 			if v < 0 {
       
   507 				return 0, errNegativeNotAllowed
       
   508 			}
   427 			return uint(v), nil
   509 			return uint(v), nil
   428 		}
   510 		}
   429 		return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
   511 		return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
   430 	case int:
   512 	case json.Number:
   431 		if s < 0 {
   513 		return ToUintE(string(s))
   432 			return 0, errNegativeNotAllowed
       
   433 		}
       
   434 		return uint(s), nil
       
   435 	case int64:
   514 	case int64:
   436 		if s < 0 {
   515 		if s < 0 {
   437 			return 0, errNegativeNotAllowed
   516 			return 0, errNegativeNotAllowed
   438 		}
   517 		}
   439 		return uint(s), nil
   518 		return uint(s), nil
   486 
   565 
   487 // ToUint64E casts an interface to a uint64 type.
   566 // ToUint64E casts an interface to a uint64 type.
   488 func ToUint64E(i interface{}) (uint64, error) {
   567 func ToUint64E(i interface{}) (uint64, error) {
   489 	i = indirect(i)
   568 	i = indirect(i)
   490 
   569 
       
   570 	intv, ok := toInt(i)
       
   571 	if ok {
       
   572 		if intv < 0 {
       
   573 			return 0, errNegativeNotAllowed
       
   574 		}
       
   575 		return uint64(intv), nil
       
   576 	}
       
   577 
   491 	switch s := i.(type) {
   578 	switch s := i.(type) {
   492 	case string:
   579 	case string:
   493 		v, err := strconv.ParseUint(s, 0, 64)
   580 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   494 		if err == nil {
   581 		if err == nil {
   495 			return v, nil
   582 			if v < 0 {
   496 		}
   583 				return 0, errNegativeNotAllowed
   497 		return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
   584 			}
   498 	case int:
   585 			return uint64(v), nil
   499 		if s < 0 {
   586 		}
   500 			return 0, errNegativeNotAllowed
   587 		return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
   501 		}
   588 	case json.Number:
   502 		return uint64(s), nil
   589 		return ToUint64E(string(s))
   503 	case int64:
   590 	case int64:
   504 		if s < 0 {
   591 		if s < 0 {
   505 			return 0, errNegativeNotAllowed
   592 			return 0, errNegativeNotAllowed
   506 		}
   593 		}
   507 		return uint64(s), nil
   594 		return uint64(s), nil
   554 
   641 
   555 // ToUint32E casts an interface to a uint32 type.
   642 // ToUint32E casts an interface to a uint32 type.
   556 func ToUint32E(i interface{}) (uint32, error) {
   643 func ToUint32E(i interface{}) (uint32, error) {
   557 	i = indirect(i)
   644 	i = indirect(i)
   558 
   645 
       
   646 	intv, ok := toInt(i)
       
   647 	if ok {
       
   648 		if intv < 0 {
       
   649 			return 0, errNegativeNotAllowed
       
   650 		}
       
   651 		return uint32(intv), nil
       
   652 	}
       
   653 
   559 	switch s := i.(type) {
   654 	switch s := i.(type) {
   560 	case string:
   655 	case string:
   561 		v, err := strconv.ParseUint(s, 0, 32)
   656 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   562 		if err == nil {
   657 		if err == nil {
       
   658 			if v < 0 {
       
   659 				return 0, errNegativeNotAllowed
       
   660 			}
   563 			return uint32(v), nil
   661 			return uint32(v), nil
   564 		}
   662 		}
   565 		return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
   663 		return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
   566 	case int:
   664 	case json.Number:
   567 		if s < 0 {
   665 		return ToUint32E(string(s))
   568 			return 0, errNegativeNotAllowed
       
   569 		}
       
   570 		return uint32(s), nil
       
   571 	case int64:
   666 	case int64:
   572 		if s < 0 {
   667 		if s < 0 {
   573 			return 0, errNegativeNotAllowed
   668 			return 0, errNegativeNotAllowed
   574 		}
   669 		}
   575 		return uint32(s), nil
   670 		return uint32(s), nil
   622 
   717 
   623 // ToUint16E casts an interface to a uint16 type.
   718 // ToUint16E casts an interface to a uint16 type.
   624 func ToUint16E(i interface{}) (uint16, error) {
   719 func ToUint16E(i interface{}) (uint16, error) {
   625 	i = indirect(i)
   720 	i = indirect(i)
   626 
   721 
       
   722 	intv, ok := toInt(i)
       
   723 	if ok {
       
   724 		if intv < 0 {
       
   725 			return 0, errNegativeNotAllowed
       
   726 		}
       
   727 		return uint16(intv), nil
       
   728 	}
       
   729 
   627 	switch s := i.(type) {
   730 	switch s := i.(type) {
   628 	case string:
   731 	case string:
   629 		v, err := strconv.ParseUint(s, 0, 16)
   732 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   630 		if err == nil {
   733 		if err == nil {
       
   734 			if v < 0 {
       
   735 				return 0, errNegativeNotAllowed
       
   736 			}
   631 			return uint16(v), nil
   737 			return uint16(v), nil
   632 		}
   738 		}
   633 		return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
   739 		return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
   634 	case int:
   740 	case json.Number:
   635 		if s < 0 {
   741 		return ToUint16E(string(s))
   636 			return 0, errNegativeNotAllowed
       
   637 		}
       
   638 		return uint16(s), nil
       
   639 	case int64:
   742 	case int64:
   640 		if s < 0 {
   743 		if s < 0 {
   641 			return 0, errNegativeNotAllowed
   744 			return 0, errNegativeNotAllowed
   642 		}
   745 		}
   643 		return uint16(s), nil
   746 		return uint16(s), nil
   690 
   793 
   691 // ToUint8E casts an interface to a uint type.
   794 // ToUint8E casts an interface to a uint type.
   692 func ToUint8E(i interface{}) (uint8, error) {
   795 func ToUint8E(i interface{}) (uint8, error) {
   693 	i = indirect(i)
   796 	i = indirect(i)
   694 
   797 
       
   798 	intv, ok := toInt(i)
       
   799 	if ok {
       
   800 		if intv < 0 {
       
   801 			return 0, errNegativeNotAllowed
       
   802 		}
       
   803 		return uint8(intv), nil
       
   804 	}
       
   805 
   695 	switch s := i.(type) {
   806 	switch s := i.(type) {
   696 	case string:
   807 	case string:
   697 		v, err := strconv.ParseUint(s, 0, 8)
   808 		v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
   698 		if err == nil {
   809 		if err == nil {
       
   810 			if v < 0 {
       
   811 				return 0, errNegativeNotAllowed
       
   812 			}
   699 			return uint8(v), nil
   813 			return uint8(v), nil
   700 		}
   814 		}
   701 		return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
   815 		return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
   702 	case int:
   816 	case json.Number:
   703 		if s < 0 {
   817 		return ToUint8E(string(s))
   704 			return 0, errNegativeNotAllowed
       
   705 		}
       
   706 		return uint8(s), nil
       
   707 	case int64:
   818 	case int64:
   708 		if s < 0 {
   819 		if s < 0 {
   709 			return 0, errNegativeNotAllowed
   820 			return 0, errNegativeNotAllowed
   710 		}
   821 		}
   711 		return uint8(s), nil
   822 		return uint8(s), nil
   826 		return strconv.FormatUint(uint64(s), 10), nil
   937 		return strconv.FormatUint(uint64(s), 10), nil
   827 	case uint16:
   938 	case uint16:
   828 		return strconv.FormatUint(uint64(s), 10), nil
   939 		return strconv.FormatUint(uint64(s), 10), nil
   829 	case uint8:
   940 	case uint8:
   830 		return strconv.FormatUint(uint64(s), 10), nil
   941 		return strconv.FormatUint(uint64(s), 10), nil
       
   942 	case json.Number:
       
   943 		return s.String(), nil
   831 	case []byte:
   944 	case []byte:
   832 		return string(s), nil
   945 		return string(s), nil
   833 	case template.HTML:
   946 	case template.HTML:
   834 		return string(s), nil
   947 		return string(s), nil
   835 	case template.URL:
   948 	case template.URL:
  1127 			a = append(a, ToString(u))
  1240 			a = append(a, ToString(u))
  1128 		}
  1241 		}
  1129 		return a, nil
  1242 		return a, nil
  1130 	case []string:
  1243 	case []string:
  1131 		return v, nil
  1244 		return v, nil
       
  1245 	case []int8:
       
  1246 		for _, u := range v {
       
  1247 			a = append(a, ToString(u))
       
  1248 		}
       
  1249 		return a, nil
       
  1250 	case []int:
       
  1251 		for _, u := range v {
       
  1252 			a = append(a, ToString(u))
       
  1253 		}
       
  1254 		return a, nil
       
  1255 	case []int32:
       
  1256 		for _, u := range v {
       
  1257 			a = append(a, ToString(u))
       
  1258 		}
       
  1259 		return a, nil
       
  1260 	case []int64:
       
  1261 		for _, u := range v {
       
  1262 			a = append(a, ToString(u))
       
  1263 		}
       
  1264 		return a, nil
       
  1265 	case []float32:
       
  1266 		for _, u := range v {
       
  1267 			a = append(a, ToString(u))
       
  1268 		}
       
  1269 		return a, nil
       
  1270 	case []float64:
       
  1271 		for _, u := range v {
       
  1272 			a = append(a, ToString(u))
       
  1273 		}
       
  1274 		return a, nil
  1132 	case string:
  1275 	case string:
  1133 		return strings.Fields(v), nil
  1276 		return strings.Fields(v), nil
       
  1277 	case []error:
       
  1278 		for _, err := range i.([]error) {
       
  1279 			a = append(a, err.Error())
       
  1280 		}
       
  1281 		return a, nil
  1134 	case interface{}:
  1282 	case interface{}:
  1135 		str, err := ToStringE(v)
  1283 		str, err := ToStringE(v)
  1136 		if err != nil {
  1284 		if err != nil {
  1137 			return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
  1285 			return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
  1138 		}
  1286 		}
  1202 
  1350 
  1203 // StringToDate attempts to parse a string into a time.Time type using a
  1351 // StringToDate attempts to parse a string into a time.Time type using a
  1204 // predefined list of formats.  If no suitable format is found, an error is
  1352 // predefined list of formats.  If no suitable format is found, an error is
  1205 // returned.
  1353 // returned.
  1206 func StringToDate(s string) (time.Time, error) {
  1354 func StringToDate(s string) (time.Time, error) {
  1207 	return parseDateWith(s, []string{
  1355 	return parseDateWith(s, time.UTC, timeFormats)
  1208 		time.RFC3339,
  1356 }
  1209 		"2006-01-02T15:04:05", // iso8601 without timezone
  1357 
  1210 		time.RFC1123Z,
  1358 // StringToDateInDefaultLocation casts an empty interface to a time.Time,
  1211 		time.RFC1123,
  1359 // interpreting inputs without a timezone to be in the given location,
  1212 		time.RFC822Z,
  1360 // or the local timezone if nil.
  1213 		time.RFC822,
  1361 func StringToDateInDefaultLocation(s string, location *time.Location) (time.Time, error) {
  1214 		time.RFC850,
  1362 	return parseDateWith(s, location, timeFormats)
  1215 		time.ANSIC,
  1363 }
  1216 		time.UnixDate,
  1364 
  1217 		time.RubyDate,
  1365 type timeFormatType int
  1218 		"2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
  1366 
  1219 		"2006-01-02",
  1367 const (
  1220 		"02 Jan 2006",
  1368 	timeFormatNoTimezone timeFormatType = iota
  1221 		"2006-01-02T15:04:05-0700", // RFC3339 without timezone hh:mm colon
  1369 	timeFormatNamedTimezone
  1222 		"2006-01-02 15:04:05 -07:00",
  1370 	timeFormatNumericTimezone
  1223 		"2006-01-02 15:04:05 -0700",
  1371 	timeFormatNumericAndNamedTimezone
  1224 		"2006-01-02 15:04:05Z07:00", // RFC3339 without T
  1372 	timeFormatTimeOnly
  1225 		"2006-01-02 15:04:05Z0700",  // RFC3339 without T or timezone hh:mm colon
  1373 )
  1226 		"2006-01-02 15:04:05",
  1374 
  1227 		time.Kitchen,
  1375 type timeFormat struct {
  1228 		time.Stamp,
  1376 	format string
  1229 		time.StampMilli,
  1377 	typ    timeFormatType
  1230 		time.StampMicro,
  1378 }
  1231 		time.StampNano,
  1379 
  1232 	})
  1380 func (f timeFormat) hasTimezone() bool {
  1233 }
  1381 	// We don't include the formats with only named timezones, see
  1234 
  1382 	// https://github.com/golang/go/issues/19694#issuecomment-289103522
  1235 func parseDateWith(s string, dates []string) (d time.Time, e error) {
  1383 	return f.typ >= timeFormatNumericTimezone && f.typ <= timeFormatNumericAndNamedTimezone
  1236 	for _, dateType := range dates {
  1384 }
  1237 		if d, e = time.Parse(dateType, s); e == nil {
  1385 
       
  1386 var (
       
  1387 	timeFormats = []timeFormat{
       
  1388 		{time.RFC3339, timeFormatNumericTimezone},
       
  1389 		{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
       
  1390 		{time.RFC1123Z, timeFormatNumericTimezone},
       
  1391 		{time.RFC1123, timeFormatNamedTimezone},
       
  1392 		{time.RFC822Z, timeFormatNumericTimezone},
       
  1393 		{time.RFC822, timeFormatNamedTimezone},
       
  1394 		{time.RFC850, timeFormatNamedTimezone},
       
  1395 		{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
       
  1396 		{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone},                        // RFC3339 without timezone hh:mm colon
       
  1397 		{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone},                        // RFC3339 without T or timezone hh:mm colon
       
  1398 		{"2006-01-02 15:04:05", timeFormatNoTimezone},
       
  1399 		{time.ANSIC, timeFormatNoTimezone},
       
  1400 		{time.UnixDate, timeFormatNamedTimezone},
       
  1401 		{time.RubyDate, timeFormatNumericTimezone},
       
  1402 		{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
       
  1403 		{"2006-01-02", timeFormatNoTimezone},
       
  1404 		{"02 Jan 2006", timeFormatNoTimezone},
       
  1405 		{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
       
  1406 		{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
       
  1407 		{time.Kitchen, timeFormatTimeOnly},
       
  1408 		{time.Stamp, timeFormatTimeOnly},
       
  1409 		{time.StampMilli, timeFormatTimeOnly},
       
  1410 		{time.StampMicro, timeFormatTimeOnly},
       
  1411 		{time.StampNano, timeFormatTimeOnly},
       
  1412 	}
       
  1413 )
       
  1414 
       
  1415 func parseDateWith(s string, location *time.Location, formats []timeFormat) (d time.Time, e error) {
       
  1416 
       
  1417 	for _, format := range formats {
       
  1418 		if d, e = time.Parse(format.format, s); e == nil {
       
  1419 
       
  1420 			// Some time formats have a zone name, but no offset, so it gets
       
  1421 			// put in that zone name (not the default one passed in to us), but
       
  1422 			// without that zone's offset. So set the location manually.
       
  1423 			if format.typ <= timeFormatNamedTimezone {
       
  1424 				if location == nil {
       
  1425 					location = time.Local
       
  1426 				}
       
  1427 				year, month, day := d.Date()
       
  1428 				hour, min, sec := d.Clock()
       
  1429 				d = time.Date(year, month, day, hour, min, sec, d.Nanosecond(), location)
       
  1430 			}
       
  1431 
  1238 			return
  1432 			return
  1239 		}
  1433 		}
  1240 	}
  1434 	}
  1241 	return d, fmt.Errorf("unable to parse date: %s", s)
  1435 	return d, fmt.Errorf("unable to parse date: %s", s)
  1242 }
  1436 }
  1245 // the object passed as pointer.
  1439 // the object passed as pointer.
  1246 func jsonStringToObject(s string, v interface{}) error {
  1440 func jsonStringToObject(s string, v interface{}) error {
  1247 	data := []byte(s)
  1441 	data := []byte(s)
  1248 	return json.Unmarshal(data, v)
  1442 	return json.Unmarshal(data, v)
  1249 }
  1443 }
       
  1444 
       
  1445 // toInt returns the int value of v if v or v's underlying type
       
  1446 // is an int.
       
  1447 // Note that this will return false for int64 etc. types.
       
  1448 func toInt(v interface{}) (int, bool) {
       
  1449 	switch v := v.(type) {
       
  1450 	case int:
       
  1451 		return v, true
       
  1452 	case time.Weekday:
       
  1453 		return int(v), true
       
  1454 	case time.Month:
       
  1455 		return int(v), true
       
  1456 	default:
       
  1457 		return 0, false
       
  1458 	}
       
  1459 }
       
  1460 
       
  1461 func trimZeroDecimal(s string) string {
       
  1462 	var foundZero bool
       
  1463 	for i := len(s); i > 0; i-- {
       
  1464 		switch s[i-1] {
       
  1465 		case '.':
       
  1466 			if foundZero {
       
  1467 				return s[:i-1]
       
  1468 			}
       
  1469 		case '0':
       
  1470 			foundZero = true
       
  1471 		default:
       
  1472 			return s
       
  1473 		}
       
  1474 	}
       
  1475 	return s
       
  1476 }