mirror of https://github.com/spf13/cast.git
Misc number fixes
* Allow strings/json.Number with just zeroes after the decmial point to be converted to integer` * Allow nil in ToFloat* * Remove some test duplication * replace testify with quicktest * Enable integer and float conversion of time.Weekday values Fixes #139 Fixes #141
This commit is contained in:
parent
36a7d5b5b8
commit
2b0eb0f724
|
@ -10,7 +10,7 @@ jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go-version: [1.17.x, 1.18.x]
|
go-version: [1.16.x, 1.17.x, 1.18.x]
|
||||||
os: [ubuntu-latest, windows-latest]
|
os: [ubuntu-latest, windows-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
|
|
1000
cast_test.go
1000
cast_test.go
File diff suppressed because it is too large
Load Diff
305
caste.go
305
caste.go
|
@ -35,7 +35,7 @@ func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.
|
||||||
case string:
|
case string:
|
||||||
return StringToDateInDefaultLocation(v, location)
|
return StringToDateInDefaultLocation(v, location)
|
||||||
case json.Number:
|
case json.Number:
|
||||||
s, err1 := v.Int64()
|
s, err1 := ToInt64E(v)
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
|
return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func ToBoolE(i interface{}) (bool, error) {
|
||||||
case string:
|
case string:
|
||||||
return strconv.ParseBool(i.(string))
|
return strconv.ParseBool(i.(string))
|
||||||
case json.Number:
|
case json.Number:
|
||||||
v, err := b.Int64()
|
v, err := ToInt64E(b)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return v != 0, nil
|
return v != 0, nil
|
||||||
}
|
}
|
||||||
|
@ -119,13 +119,16 @@ func ToBoolE(i interface{}) (bool, error) {
|
||||||
func ToFloat64E(i interface{}) (float64, error) {
|
func ToFloat64E(i interface{}) (float64, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
return float64(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case float64:
|
case float64:
|
||||||
return s, nil
|
return s, nil
|
||||||
case float32:
|
case float32:
|
||||||
return float64(s), nil
|
return float64(s), nil
|
||||||
case int:
|
|
||||||
return float64(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
return float64(s), nil
|
return float64(s), nil
|
||||||
case int32:
|
case int32:
|
||||||
|
@ -161,6 +164,8 @@ func ToFloat64E(i interface{}) (float64, error) {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
return 0, nil
|
return 0, nil
|
||||||
|
case nil:
|
||||||
|
return 0, nil
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
|
||||||
}
|
}
|
||||||
|
@ -170,13 +175,16 @@ func ToFloat64E(i interface{}) (float64, error) {
|
||||||
func ToFloat32E(i interface{}) (float32, error) {
|
func ToFloat32E(i interface{}) (float32, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
return float32(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case float64:
|
case float64:
|
||||||
return float32(s), nil
|
return float32(s), nil
|
||||||
case float32:
|
case float32:
|
||||||
return s, nil
|
return s, nil
|
||||||
case int:
|
|
||||||
return float32(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
return float32(s), nil
|
return float32(s), nil
|
||||||
case int32:
|
case int32:
|
||||||
|
@ -212,6 +220,8 @@ func ToFloat32E(i interface{}) (float32, error) {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
return 0, nil
|
return 0, nil
|
||||||
|
case nil:
|
||||||
|
return 0, nil
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
|
||||||
}
|
}
|
||||||
|
@ -221,9 +231,12 @@ func ToFloat32E(i interface{}) (float32, error) {
|
||||||
func ToInt64E(i interface{}) (int64, error) {
|
func ToInt64E(i interface{}) (int64, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
return int64(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case int:
|
|
||||||
return int64(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
return s, nil
|
return s, nil
|
||||||
case int32:
|
case int32:
|
||||||
|
@ -247,17 +260,13 @@ func ToInt64E(i interface{}) (int64, error) {
|
||||||
case float32:
|
case float32:
|
||||||
return int64(s), nil
|
return int64(s), nil
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseInt(s, 0, 0)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
|
||||||
case json.Number:
|
case json.Number:
|
||||||
v, err := s.Int64()
|
return ToInt64E(string(s))
|
||||||
if err == nil {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
|
|
||||||
case bool:
|
case bool:
|
||||||
if s {
|
if s {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
|
@ -274,9 +283,12 @@ func ToInt64E(i interface{}) (int64, error) {
|
||||||
func ToInt32E(i interface{}) (int32, error) {
|
func ToInt32E(i interface{}) (int32, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
return int32(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case int:
|
|
||||||
return int32(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
return int32(s), nil
|
return int32(s), nil
|
||||||
case int32:
|
case int32:
|
||||||
|
@ -300,17 +312,13 @@ func ToInt32E(i interface{}) (int32, error) {
|
||||||
case float32:
|
case float32:
|
||||||
return int32(s), nil
|
return int32(s), nil
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseInt(s, 0, 0)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return int32(v), nil
|
return int32(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
|
||||||
case json.Number:
|
case json.Number:
|
||||||
v, err := s.Int64()
|
return ToInt32E(string(s))
|
||||||
if err == nil {
|
|
||||||
return int32(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
|
|
||||||
case bool:
|
case bool:
|
||||||
if s {
|
if s {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
|
@ -327,9 +335,12 @@ func ToInt32E(i interface{}) (int32, error) {
|
||||||
func ToInt16E(i interface{}) (int16, error) {
|
func ToInt16E(i interface{}) (int16, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
return int16(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case int:
|
|
||||||
return int16(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
return int16(s), nil
|
return int16(s), nil
|
||||||
case int32:
|
case int32:
|
||||||
|
@ -353,17 +364,13 @@ func ToInt16E(i interface{}) (int16, error) {
|
||||||
case float32:
|
case float32:
|
||||||
return int16(s), nil
|
return int16(s), nil
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseInt(s, 0, 0)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return int16(v), nil
|
return int16(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
|
||||||
case json.Number:
|
case json.Number:
|
||||||
v, err := s.Int64()
|
return ToInt16E(string(s))
|
||||||
if err == nil {
|
|
||||||
return int16(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
|
|
||||||
case bool:
|
case bool:
|
||||||
if s {
|
if s {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
|
@ -380,9 +387,12 @@ func ToInt16E(i interface{}) (int16, error) {
|
||||||
func ToInt8E(i interface{}) (int8, error) {
|
func ToInt8E(i interface{}) (int8, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
return int8(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case int:
|
|
||||||
return int8(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
return int8(s), nil
|
return int8(s), nil
|
||||||
case int32:
|
case int32:
|
||||||
|
@ -406,17 +416,13 @@ func ToInt8E(i interface{}) (int8, error) {
|
||||||
case float32:
|
case float32:
|
||||||
return int8(s), nil
|
return int8(s), nil
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseInt(s, 0, 0)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return int8(v), nil
|
return int8(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
|
||||||
case json.Number:
|
case json.Number:
|
||||||
v, err := s.Int64()
|
return ToInt8E(string(s))
|
||||||
if err == nil {
|
|
||||||
return int8(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
|
|
||||||
case bool:
|
case bool:
|
||||||
if s {
|
if s {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
|
@ -433,9 +439,12 @@ func ToInt8E(i interface{}) (int8, error) {
|
||||||
func ToIntE(i interface{}) (int, error) {
|
func ToIntE(i interface{}) (int, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
return intv, nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case int:
|
|
||||||
return s, nil
|
|
||||||
case int64:
|
case int64:
|
||||||
return int(s), nil
|
return int(s), nil
|
||||||
case int32:
|
case int32:
|
||||||
|
@ -459,17 +468,13 @@ func ToIntE(i interface{}) (int, error) {
|
||||||
case float32:
|
case float32:
|
||||||
return int(s), nil
|
return int(s), nil
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseInt(s, 0, 0)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return int(v), nil
|
return int(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
|
||||||
case json.Number:
|
case json.Number:
|
||||||
v, err := s.Int64()
|
return ToIntE(string(s))
|
||||||
if err == nil {
|
|
||||||
return int(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
|
|
||||||
case bool:
|
case bool:
|
||||||
if s {
|
if s {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
|
@ -486,27 +491,26 @@ func ToIntE(i interface{}) (int, error) {
|
||||||
func ToUintE(i interface{}) (uint, error) {
|
func ToUintE(i interface{}) (uint, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
if intv < 0 {
|
||||||
|
return 0, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
return uint(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseUint(s, 0, 0)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
|
||||||
return uint(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
|
|
||||||
case json.Number:
|
|
||||||
v, err := s.Int64()
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
}
|
}
|
||||||
return uint(v), nil
|
return uint(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
|
||||||
case int:
|
case json.Number:
|
||||||
if s < 0 {
|
return ToUintE(string(s))
|
||||||
return 0, errNegativeNotAllowed
|
|
||||||
}
|
|
||||||
return uint(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
if s < 0 {
|
if s < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
|
@ -563,27 +567,26 @@ func ToUintE(i interface{}) (uint, error) {
|
||||||
func ToUint64E(i interface{}) (uint64, error) {
|
func ToUint64E(i interface{}) (uint64, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
if intv < 0 {
|
||||||
|
return 0, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
return uint64(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseUint(s, 0, 64)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
|
|
||||||
case json.Number:
|
|
||||||
v, err := s.Int64()
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
}
|
}
|
||||||
return uint64(v), nil
|
return uint64(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
|
||||||
case int:
|
case json.Number:
|
||||||
if s < 0 {
|
return ToUint64E(string(s))
|
||||||
return 0, errNegativeNotAllowed
|
|
||||||
}
|
|
||||||
return uint64(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
if s < 0 {
|
if s < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
|
@ -640,27 +643,26 @@ func ToUint64E(i interface{}) (uint64, error) {
|
||||||
func ToUint32E(i interface{}) (uint32, error) {
|
func ToUint32E(i interface{}) (uint32, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
if intv < 0 {
|
||||||
|
return 0, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
return uint32(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseUint(s, 0, 32)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
|
||||||
return uint32(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
|
|
||||||
case json.Number:
|
|
||||||
v, err := s.Int64()
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
}
|
}
|
||||||
return uint32(v), nil
|
return uint32(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
|
||||||
case int:
|
case json.Number:
|
||||||
if s < 0 {
|
return ToUint32E(string(s))
|
||||||
return 0, errNegativeNotAllowed
|
|
||||||
}
|
|
||||||
return uint32(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
if s < 0 {
|
if s < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
|
@ -717,27 +719,26 @@ func ToUint32E(i interface{}) (uint32, error) {
|
||||||
func ToUint16E(i interface{}) (uint16, error) {
|
func ToUint16E(i interface{}) (uint16, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
if intv < 0 {
|
||||||
|
return 0, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
return uint16(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseUint(s, 0, 16)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
|
||||||
return uint16(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
|
|
||||||
case json.Number:
|
|
||||||
v, err := s.Int64()
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
}
|
}
|
||||||
return uint16(v), nil
|
return uint16(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
|
||||||
case int:
|
case json.Number:
|
||||||
if s < 0 {
|
return ToUint16E(string(s))
|
||||||
return 0, errNegativeNotAllowed
|
|
||||||
}
|
|
||||||
return uint16(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
if s < 0 {
|
if s < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
|
@ -794,27 +795,26 @@ func ToUint16E(i interface{}) (uint16, error) {
|
||||||
func ToUint8E(i interface{}) (uint8, error) {
|
func ToUint8E(i interface{}) (uint8, error) {
|
||||||
i = indirect(i)
|
i = indirect(i)
|
||||||
|
|
||||||
|
intv, ok := toInt(i)
|
||||||
|
if ok {
|
||||||
|
if intv < 0 {
|
||||||
|
return 0, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
return uint8(intv), nil
|
||||||
|
}
|
||||||
|
|
||||||
switch s := i.(type) {
|
switch s := i.(type) {
|
||||||
case string:
|
case string:
|
||||||
v, err := strconv.ParseUint(s, 0, 8)
|
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||||
if err == nil {
|
|
||||||
return uint8(v), nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
|
|
||||||
case json.Number:
|
|
||||||
v, err := s.Int64()
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
}
|
}
|
||||||
return uint8(v), nil
|
return uint8(v), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
|
return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
|
||||||
case int:
|
case json.Number:
|
||||||
if s < 0 {
|
return ToUint8E(string(s))
|
||||||
return 0, errNegativeNotAllowed
|
|
||||||
}
|
|
||||||
return uint8(s), nil
|
|
||||||
case int64:
|
case int64:
|
||||||
if s < 0 {
|
if s < 0 {
|
||||||
return 0, errNegativeNotAllowed
|
return 0, errNegativeNotAllowed
|
||||||
|
@ -1385,30 +1385,30 @@ func (f timeFormat) hasTimezone() bool {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
timeFormats = []timeFormat{
|
timeFormats = []timeFormat{
|
||||||
timeFormat{time.RFC3339, timeFormatNumericTimezone},
|
{time.RFC3339, timeFormatNumericTimezone},
|
||||||
timeFormat{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
|
{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
|
||||||
timeFormat{time.RFC1123Z, timeFormatNumericTimezone},
|
{time.RFC1123Z, timeFormatNumericTimezone},
|
||||||
timeFormat{time.RFC1123, timeFormatNamedTimezone},
|
{time.RFC1123, timeFormatNamedTimezone},
|
||||||
timeFormat{time.RFC822Z, timeFormatNumericTimezone},
|
{time.RFC822Z, timeFormatNumericTimezone},
|
||||||
timeFormat{time.RFC822, timeFormatNamedTimezone},
|
{time.RFC822, timeFormatNamedTimezone},
|
||||||
timeFormat{time.RFC850, timeFormatNamedTimezone},
|
{time.RFC850, timeFormatNamedTimezone},
|
||||||
timeFormat{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
|
{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
|
||||||
timeFormat{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
|
{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
|
||||||
timeFormat{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
|
{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
|
||||||
timeFormat{"2006-01-02 15:04:05", timeFormatNoTimezone},
|
{"2006-01-02 15:04:05", timeFormatNoTimezone},
|
||||||
timeFormat{time.ANSIC, timeFormatNoTimezone},
|
{time.ANSIC, timeFormatNoTimezone},
|
||||||
timeFormat{time.UnixDate, timeFormatNamedTimezone},
|
{time.UnixDate, timeFormatNamedTimezone},
|
||||||
timeFormat{time.RubyDate, timeFormatNumericTimezone},
|
{time.RubyDate, timeFormatNumericTimezone},
|
||||||
timeFormat{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
|
{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
|
||||||
timeFormat{"2006-01-02", timeFormatNoTimezone},
|
{"2006-01-02", timeFormatNoTimezone},
|
||||||
timeFormat{"02 Jan 2006", timeFormatNoTimezone},
|
{"02 Jan 2006", timeFormatNoTimezone},
|
||||||
timeFormat{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
|
{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
|
||||||
timeFormat{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
|
{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
|
||||||
timeFormat{time.Kitchen, timeFormatTimeOnly},
|
{time.Kitchen, timeFormatTimeOnly},
|
||||||
timeFormat{time.Stamp, timeFormatTimeOnly},
|
{time.Stamp, timeFormatTimeOnly},
|
||||||
timeFormat{time.StampMilli, timeFormatTimeOnly},
|
{time.StampMilli, timeFormatTimeOnly},
|
||||||
timeFormat{time.StampMicro, timeFormatTimeOnly},
|
{time.StampMicro, timeFormatTimeOnly},
|
||||||
timeFormat{time.StampNano, timeFormatTimeOnly},
|
{time.StampNano, timeFormatTimeOnly},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1441,3 +1441,36 @@ func jsonStringToObject(s string, v interface{}) error {
|
||||||
data := []byte(s)
|
data := []byte(s)
|
||||||
return json.Unmarshal(data, v)
|
return json.Unmarshal(data, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// toInt returns the int value of v if v or v's underlying type
|
||||||
|
// is an int.
|
||||||
|
// Note that this will return false for int64 etc. types.
|
||||||
|
func toInt(v interface{}) (int, bool) {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case int:
|
||||||
|
return v, true
|
||||||
|
case time.Weekday:
|
||||||
|
return int(v), true
|
||||||
|
case time.Month:
|
||||||
|
return int(v), true
|
||||||
|
default:
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func trimZeroDecimal(s string) string {
|
||||||
|
var foundZero bool
|
||||||
|
for i := len(s); i > 0; i-- {
|
||||||
|
switch s[i-1] {
|
||||||
|
case '.':
|
||||||
|
if foundZero {
|
||||||
|
return s[:i-1]
|
||||||
|
}
|
||||||
|
case '0':
|
||||||
|
foundZero = true
|
||||||
|
default:
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
12
go.mod
12
go.mod
|
@ -1,7 +1,13 @@
|
||||||
module github.com/spf13/cast
|
module github.com/spf13/cast
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/frankban/quicktest v1.14.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/google/go-cmp v0.5.7 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/kr/pretty v0.3.0 // indirect
|
||||||
github.com/stretchr/testify v1.2.2
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.6.1 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
|
||||||
)
|
)
|
||||||
|
|
24
go.sum
24
go.sum
|
@ -1,6 +1,18 @@
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
|
Loading…
Reference in New Issue