Add additional type conversions

Adds float32, uint, uint64, uint32, uint16, and uint8 throughout.

Fixes #33
This commit is contained in:
Cameron Moore 2017-03-03 13:44:11 -06:00 committed by Bjørn Erik Pedersen
parent df9611b942
commit d37435d953
3 changed files with 765 additions and 35 deletions

36
cast.go
View File

@ -32,6 +32,12 @@ func ToFloat64(i interface{}) float64 {
return v return v
} }
// ToFloat32 casts an interface to a float32 type.
func ToFloat32(i interface{}) float32 {
v, _ := ToFloat32E(i)
return v
}
// ToInt64 casts an interface to an int64 type. // ToInt64 casts an interface to an int64 type.
func ToInt64(i interface{}) int64 { func ToInt64(i interface{}) int64 {
v, _ := ToInt64E(i) v, _ := ToInt64E(i)
@ -62,6 +68,36 @@ func ToInt(i interface{}) int {
return v return v
} }
// ToUint casts an interface to a uint type.
func ToUint(i interface{}) uint {
v, _ := ToUintE(i)
return v
}
// ToUint64 casts an interface to a uint64 type.
func ToUint64(i interface{}) uint64 {
v, _ := ToUint64E(i)
return v
}
// ToUint32 casts an interface to a uint32 type.
func ToUint32(i interface{}) uint32 {
v, _ := ToUint32E(i)
return v
}
// ToUint16 casts an interface to a uint16 type.
func ToUint16(i interface{}) uint16 {
v, _ := ToUint16E(i)
return v
}
// ToUint8 casts an interface to a uint8 type.
func ToUint8(i interface{}) uint8 {
v, _ := ToUint8E(i)
return v
}
// ToString casts an interface to a string type. // ToString casts an interface to a string type.
func ToString(i interface{}) string { func ToString(i interface{}) string {
v, _ := ToStringE(i) v, _ := ToStringE(i)

View File

@ -14,6 +14,231 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestToUintE(t *testing.T) {
tests := []struct {
input interface{}
expect uint
iserr bool
}{
{int(8), 8, false},
{int8(8), 8, false},
{int16(8), 8, false},
{int32(8), 8, false},
{int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false},
{true, 1, false},
{false, 0, false},
{"8", 8, false},
{nil, 0, false},
// errors
{"test", 0, true},
{testing.T{}, 0, true},
}
for i, test := range tests {
errmsg := fmt.Sprintf("i = %d", i) // assert helper message
v, err := ToUintE(test.input)
if test.iserr {
assert.Error(t, err, errmsg)
continue
}
assert.NoError(t, err, errmsg)
assert.Equal(t, test.expect, v, errmsg)
// Non-E test:
v = ToUint(test.input)
assert.Equal(t, test.expect, v, errmsg)
}
}
func TestToUint64E(t *testing.T) {
tests := []struct {
input interface{}
expect uint64
iserr bool
}{
{int(8), 8, false},
{int8(8), 8, false},
{int16(8), 8, false},
{int32(8), 8, false},
{int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false},
{true, 1, false},
{false, 0, false},
{"8", 8, false},
{nil, 0, false},
// errors
{"test", 0, true},
{testing.T{}, 0, true},
}
for i, test := range tests {
errmsg := fmt.Sprintf("i = %d", i) // assert helper message
v, err := ToUint64E(test.input)
if test.iserr {
assert.Error(t, err, errmsg)
continue
}
assert.NoError(t, err, errmsg)
assert.Equal(t, test.expect, v, errmsg)
// Non-E test:
v = ToUint64(test.input)
assert.Equal(t, test.expect, v, errmsg)
}
}
func TestToUint32E(t *testing.T) {
tests := []struct {
input interface{}
expect uint32
iserr bool
}{
{int(8), 8, false},
{int8(8), 8, false},
{int16(8), 8, false},
{int32(8), 8, false},
{int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false},
{true, 1, false},
{false, 0, false},
{"8", 8, false},
{nil, 0, false},
// errors
{"test", 0, true},
{testing.T{}, 0, true},
}
for i, test := range tests {
errmsg := fmt.Sprintf("i = %d", i) // assert helper message
v, err := ToUint32E(test.input)
if test.iserr {
assert.Error(t, err, errmsg)
continue
}
assert.NoError(t, err, errmsg)
assert.Equal(t, test.expect, v, errmsg)
// Non-E test:
v = ToUint32(test.input)
assert.Equal(t, test.expect, v, errmsg)
}
}
func TestToUint16E(t *testing.T) {
tests := []struct {
input interface{}
expect uint16
iserr bool
}{
{int(8), 8, false},
{int8(8), 8, false},
{int16(8), 8, false},
{int32(8), 8, false},
{int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false},
{true, 1, false},
{false, 0, false},
{"8", 8, false},
{nil, 0, false},
// errors
{"test", 0, true},
{testing.T{}, 0, true},
}
for i, test := range tests {
errmsg := fmt.Sprintf("i = %d", i) // assert helper message
v, err := ToUint16E(test.input)
if test.iserr {
assert.Error(t, err, errmsg)
continue
}
assert.NoError(t, err, errmsg)
assert.Equal(t, test.expect, v, errmsg)
// Non-E test
v = ToUint16(test.input)
assert.Equal(t, test.expect, v, errmsg)
}
}
func TestToUint8E(t *testing.T) {
tests := []struct {
input interface{}
expect uint8
iserr bool
}{
{int(8), 8, false},
{int8(8), 8, false},
{int16(8), 8, false},
{int32(8), 8, false},
{int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false},
{true, 1, false},
{false, 0, false},
{"8", 8, false},
{nil, 0, false},
// errors
{"test", 0, true},
{testing.T{}, 0, true},
}
for i, test := range tests {
errmsg := fmt.Sprintf("i = %d", i) // assert helper message
v, err := ToUint8E(test.input)
if test.iserr {
assert.Error(t, err, errmsg)
continue
}
assert.NoError(t, err, errmsg)
assert.Equal(t, test.expect, v, errmsg)
// Non-E test
v = ToUint8(test.input)
assert.Equal(t, test.expect, v, errmsg)
}
}
func TestToIntE(t *testing.T) { func TestToIntE(t *testing.T) {
tests := []struct { tests := []struct {
input interface{} input interface{}
@ -25,6 +250,12 @@ func TestToIntE(t *testing.T) {
{int16(8), 8, false}, {int16(8), 8, false},
{int32(8), 8, false}, {int32(8), 8, false},
{int64(8), 8, false}, {int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false}, {float64(8.31), 8, false},
{true, 1, false}, {true, 1, false},
{false, 0, false}, {false, 0, false},
@ -64,6 +295,12 @@ func TestToInt64E(t *testing.T) {
{int16(8), 8, false}, {int16(8), 8, false},
{int32(8), 8, false}, {int32(8), 8, false},
{int64(8), 8, false}, {int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false}, {float64(8.31), 8, false},
{true, 1, false}, {true, 1, false},
{false, 0, false}, {false, 0, false},
@ -103,6 +340,12 @@ func TestToInt32E(t *testing.T) {
{int16(8), 8, false}, {int16(8), 8, false},
{int32(8), 8, false}, {int32(8), 8, false},
{int64(8), 8, false}, {int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false}, {float64(8.31), 8, false},
{true, 1, false}, {true, 1, false},
{false, 0, false}, {false, 0, false},
@ -142,6 +385,12 @@ func TestToInt16E(t *testing.T) {
{int16(8), 8, false}, {int16(8), 8, false},
{int32(8), 8, false}, {int32(8), 8, false},
{int64(8), 8, false}, {int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false}, {float64(8.31), 8, false},
{true, 1, false}, {true, 1, false},
{false, 0, false}, {false, 0, false},
@ -181,6 +430,12 @@ func TestToInt8E(t *testing.T) {
{int16(8), 8, false}, {int16(8), 8, false},
{int32(8), 8, false}, {int32(8), 8, false},
{int64(8), 8, false}, {int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8, false},
{float64(8.31), 8, false}, {float64(8.31), 8, false},
{true, 1, false}, {true, 1, false},
{false, 0, false}, {false, 0, false},
@ -220,9 +475,16 @@ func TestToFloat64E(t *testing.T) {
{int16(8), 8, false}, {int16(8), 8, false},
{int32(8), 8, false}, {int32(8), 8, false},
{int64(8), 8, false}, {int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8), 8, false}, {float32(8), 8, false},
{float64(8.31), 8.31, false}, {float64(8.31), 8.31, false},
{"8", 8, false}, {"8", 8, false},
{true, 1, false},
{false, 0, false},
// errors // errors
{"test", 0, true}, {"test", 0, true},
{testing.T{}, 0, true}, {testing.T{}, 0, true},
@ -246,6 +508,50 @@ func TestToFloat64E(t *testing.T) {
} }
} }
func TestToFloat32E(t *testing.T) {
tests := []struct {
input interface{}
expect float32
iserr bool
}{
{int(8), 8, false},
{int8(8), 8, false},
{int16(8), 8, false},
{int32(8), 8, false},
{int64(8), 8, false},
{uint(8), 8, false},
{uint8(8), 8, false},
{uint16(8), 8, false},
{uint32(8), 8, false},
{uint64(8), 8, false},
{float32(8.31), 8.31, false},
{float64(8.31), 8.31, false},
{"8", 8, false},
{true, 1, false},
{false, 0, false},
// errors
{"test", 0, true},
{testing.T{}, 0, true},
}
for i, test := range tests {
errmsg := fmt.Sprintf("i = %d", i) // assert helper message
v, err := ToFloat32E(test.input)
if test.iserr {
assert.Error(t, err, errmsg)
continue
}
assert.NoError(t, err, errmsg)
assert.Equal(t, test.expect, v, errmsg)
// Non-E test
v = ToFloat32(test.input)
assert.Equal(t, test.expect, v, errmsg)
}
}
func TestToStringE(t *testing.T) { func TestToStringE(t *testing.T) {
type Key struct { type Key struct {
k string k string
@ -258,7 +564,16 @@ func TestToStringE(t *testing.T) {
iserr bool iserr bool
}{ }{
{int(8), "8", false}, {int(8), "8", false},
{int8(8), "8", false},
{int16(8), "8", false},
{int32(8), "8", false},
{int64(8), "8", false}, {int64(8), "8", false},
{uint(8), "8", false},
{uint8(8), "8", false},
{uint16(8), "8", false},
{uint32(8), "8", false},
{uint64(8), "8", false},
{float32(8.31), "8.31", false},
{float64(8.31), "8.31", false}, {float64(8.31), "8.31", false},
{true, "true", false}, {true, "true", false},
{false, "false", false}, {false, "false", false},
@ -716,6 +1031,9 @@ func TestToTimeEE(t *testing.T) {
{int(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false}, {int(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
{int64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false}, {int64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
{int32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false}, {int32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
{uint(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
{uint64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
{uint32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
{time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false}, {time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
// errors // errors
{"2006", time.Time{}, true}, {"2006", time.Time{}, true},
@ -754,7 +1072,13 @@ func TestToDurationE(t *testing.T) {
{int32(5), td, false}, {int32(5), td, false},
{int16(5), td, false}, {int16(5), td, false},
{int8(5), td, false}, {int8(5), td, false},
{uint(5), td, false},
{uint64(5), td, false},
{uint32(5), td, false},
{uint16(5), td, false},
{uint8(5), td, false},
{float64(5), td, false}, {float64(5), td, false},
{float32(5), td, false},
{string("5"), td, false}, {string("5"), td, false},
{string("5ns"), td, false}, {string("5ns"), td, false},
{string("5us"), time.Microsecond * td, false}, {string("5us"), time.Microsecond * td, false},

440
caste.go
View File

@ -25,10 +25,16 @@ func ToTimeE(i interface{}) (tim time.Time, err error) {
return StringToDate(v) return StringToDate(v)
case int: case int:
return time.Unix(int64(v), 0), nil return time.Unix(int64(v), 0), nil
case int32:
return time.Unix(int64(v), 0), nil
case int64: case int64:
return time.Unix(v, 0), nil return time.Unix(v, 0), nil
case int32:
return time.Unix(int64(v), 0), nil
case uint:
return time.Unix(int64(v), 0), nil
case uint64:
return time.Unix(int64(v), 0), nil
case uint32:
return time.Unix(int64(v), 0), nil
default: default:
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)
} }
@ -41,7 +47,7 @@ func ToDurationE(i interface{}) (d time.Duration, err error) {
switch s := i.(type) { switch s := i.(type) {
case time.Duration: case time.Duration:
return s, nil return s, nil
case int64, int32, int16, int8, int: case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
d = time.Duration(ToInt64(s)) d = time.Duration(ToInt64(s))
return return
case float32, float64: case float32, float64:
@ -62,7 +68,6 @@ func ToDurationE(i interface{}) (d time.Duration, err error) {
// ToBoolE casts an interface to a bool type. // ToBoolE casts an interface to a bool type.
func ToBoolE(i interface{}) (bool, error) { func ToBoolE(i interface{}) (bool, error) {
i = indirect(i) i = indirect(i)
switch b := i.(type) { switch b := i.(type) {
@ -91,6 +96,8 @@ func ToFloat64E(i interface{}) (float64, error) {
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:
@ -99,16 +106,74 @@ func ToFloat64E(i interface{}) (float64, error) {
return float64(s), nil return float64(s), nil
case int8: case int8:
return float64(s), nil return float64(s), nil
case int: case uint:
return float64(s), nil
case uint64:
return float64(s), nil
case uint32:
return float64(s), nil
case uint16:
return float64(s), nil
case uint8:
return float64(s), nil return float64(s), nil
case string: case string:
v, err := strconv.ParseFloat(s, 64) v, err := strconv.ParseFloat(s, 64)
if err == nil { if err == nil {
return float64(v), nil return float64(v), nil
} }
return 0.0, fmt.Errorf("unable to cast %#v of type %T to float", i, i) return 0.0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
case bool:
if s {
return 1, nil
}
return 0, nil
default: default:
return 0.0, fmt.Errorf("unable to cast %#v of type %T to float", i, i) return 0.0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
}
}
// ToFloat32E casts an interface to a float32 type.
func ToFloat32E(i interface{}) (float32, error) {
i = indirect(i)
switch s := i.(type) {
case float64:
return float32(s), nil
case float32:
return s, nil
case int:
return float32(s), nil
case int64:
return float32(s), nil
case int32:
return float32(s), nil
case int16:
return float32(s), nil
case int8:
return float32(s), nil
case uint:
return float32(s), nil
case uint64:
return float32(s), nil
case uint32:
return float32(s), nil
case uint16:
return float32(s), nil
case uint8:
return float32(s), nil
case string:
v, err := strconv.ParseFloat(s, 32)
if err == nil {
return float32(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
case bool:
if s {
return 1, nil
}
return 0, nil
default:
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
} }
} }
@ -117,24 +182,36 @@ func ToInt64E(i interface{}) (int64, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { switch s := i.(type) {
case int64:
return s, nil
case int: case int:
return int64(s), nil return int64(s), nil
case int64:
return s, nil
case int32: case int32:
return int64(s), nil return int64(s), nil
case int16: case int16:
return int64(s), nil return int64(s), nil
case int8: case int8:
return int64(s), nil return int64(s), nil
case uint:
return int64(s), nil
case uint64:
return int64(s), nil
case uint32:
return int64(s), nil
case uint16:
return int64(s), nil
case uint8:
return int64(s), nil
case float64:
return int64(s), nil
case float32:
return int64(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(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 float64:
return int64(s), nil
case bool: case bool:
if bool(s) { if bool(s) {
return int64(1), nil return int64(1), nil
@ -152,24 +229,36 @@ func ToInt32E(i interface{}) (int32, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { switch s := i.(type) {
case int64:
return int32(s), nil
case int: case int:
return int32(s), nil return int32(s), nil
case int64:
return int32(s), nil
case int32: case int32:
return s, nil return s, nil
case int16: case int16:
return int32(s), nil return int32(s), nil
case int8: case int8:
return int32(s), nil return int32(s), nil
case uint:
return int32(s), nil
case uint64:
return int32(s), nil
case uint32:
return int32(s), nil
case uint16:
return int32(s), nil
case uint8:
return int32(s), nil
case float64:
return int32(s), nil
case float32:
return int32(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(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 float64:
return int32(s), nil
case bool: case bool:
if bool(s) { if bool(s) {
return int32(1), nil return int32(1), nil
@ -187,24 +276,36 @@ func ToInt16E(i interface{}) (int16, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { switch s := i.(type) {
case int64:
return int16(s), nil
case int: case int:
return int16(s), nil return int16(s), nil
case int64:
return int16(s), nil
case int32: case int32:
return int16(s), nil return int16(s), nil
case int16: case int16:
return s, nil return s, nil
case int8: case int8:
return int16(s), nil return int16(s), nil
case uint:
return int16(s), nil
case uint64:
return int16(s), nil
case uint32:
return int16(s), nil
case uint16:
return int16(s), nil
case uint8:
return int16(s), nil
case float64:
return int16(s), nil
case float32:
return int16(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(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 float64:
return int16(s), nil
case bool: case bool:
if bool(s) { if bool(s) {
return int16(1), nil return int16(1), nil
@ -222,24 +323,36 @@ func ToInt8E(i interface{}) (int8, error) {
i = indirect(i) i = indirect(i)
switch s := i.(type) { switch s := i.(type) {
case int64:
return int8(s), nil
case int: case int:
return int8(s), nil return int8(s), nil
case int64:
return int8(s), nil
case int32: case int32:
return int8(s), nil return int8(s), nil
case int16: case int16:
return int8(s), nil return int8(s), nil
case int8: case int8:
return s, nil return s, nil
case uint:
return int8(s), nil
case uint64:
return int8(s), nil
case uint32:
return int8(s), nil
case uint16:
return int8(s), nil
case uint8:
return int8(s), nil
case float64:
return int8(s), nil
case float32:
return int8(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(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 float64:
return int8(s), nil
case bool: case bool:
if bool(s) { if bool(s) {
return int8(1), nil return int8(1), nil
@ -267,14 +380,26 @@ func ToIntE(i interface{}) (int, error) {
return int(s), nil return int(s), nil
case int8: case int8:
return int(s), nil return int(s), nil
case uint:
return int(s), nil
case uint64:
return int(s), nil
case uint32:
return int(s), nil
case uint16:
return int(s), nil
case uint8:
return int(s), nil
case float64:
return int(s), nil
case float32:
return int(s), nil
case string: case string:
v, err := strconv.ParseInt(s, 0, 0) v, err := strconv.ParseInt(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 int", i, i)
case float64:
return int(s), nil
case bool: case bool:
if bool(s) { if bool(s) {
return 1, nil return 1, nil
@ -287,6 +412,241 @@ func ToIntE(i interface{}) (int, error) {
} }
} }
// ToUintE casts an interface to a uint type.
func ToUintE(i interface{}) (uint, error) {
i = indirect(i)
switch s := i.(type) {
case string:
v, err := strconv.ParseUint(s, 0, 0)
if err == nil {
return uint(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
case int:
return uint(s), nil
case int64:
return uint(s), nil
case int32:
return uint(s), nil
case int16:
return uint(s), nil
case int8:
return uint(s), nil
case uint:
return s, nil
case uint64:
return uint(s), nil
case uint32:
return uint(s), nil
case uint16:
return uint(s), nil
case uint8:
return uint(s), nil
case float64:
return uint(s), nil
case float32:
return uint(s), nil
case bool:
if s {
return 1, nil
}
return 0, nil
case nil:
return 0, nil
default:
return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
}
}
// ToUint64E casts an interface to a uint64 type.
func ToUint64E(i interface{}) (uint64, error) {
i = indirect(i)
switch s := i.(type) {
case string:
v, err := strconv.ParseUint(s, 0, 64)
if err == nil {
return v, nil
}
return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
case int:
return uint64(s), nil
case int64:
return uint64(s), nil
case int32:
return uint64(s), nil
case int16:
return uint64(s), nil
case int8:
return uint64(s), nil
case uint:
return uint64(s), nil
case uint64:
return s, nil
case uint32:
return uint64(s), nil
case uint16:
return uint64(s), nil
case uint8:
return uint64(s), nil
case float32:
return uint64(s), nil
case float64:
return uint64(s), nil
case bool:
if s {
return 1, nil
}
return 0, nil
case nil:
return 0, nil
default:
return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
}
}
// ToUint32E casts an interface to a uint32 type.
func ToUint32E(i interface{}) (uint32, error) {
i = indirect(i)
switch s := i.(type) {
case string:
v, err := strconv.ParseUint(s, 0, 32)
if err == nil {
return uint32(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
case int:
return uint32(s), nil
case int64:
return uint32(s), nil
case int32:
return uint32(s), nil
case int16:
return uint32(s), nil
case int8:
return uint32(s), nil
case uint:
return uint32(s), nil
case uint64:
return uint32(s), nil
case uint32:
return s, nil
case uint16:
return uint32(s), nil
case uint8:
return uint32(s), nil
case float64:
return uint32(s), nil
case float32:
return uint32(s), nil
case bool:
if s {
return 1, nil
}
return 0, nil
case nil:
return 0, nil
default:
return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
}
}
// ToUint16E casts an interface to a uint16 type.
func ToUint16E(i interface{}) (uint16, error) {
i = indirect(i)
switch s := i.(type) {
case string:
v, err := strconv.ParseUint(s, 0, 16)
if err == nil {
return uint16(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
case int:
return uint16(s), nil
case int64:
return uint16(s), nil
case int32:
return uint16(s), nil
case int16:
return uint16(s), nil
case int8:
return uint16(s), nil
case uint:
return uint16(s), nil
case uint64:
return uint16(s), nil
case uint32:
return uint16(s), nil
case uint16:
return s, nil
case uint8:
return uint16(s), nil
case float64:
return uint16(s), nil
case float32:
return uint16(s), nil
case bool:
if s {
return 1, nil
}
return 0, nil
case nil:
return 0, nil
default:
return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
}
}
// ToUint8E casts an interface to a uint type.
func ToUint8E(i interface{}) (uint8, error) {
i = indirect(i)
switch s := i.(type) {
case string:
v, err := strconv.ParseUint(s, 0, 8)
if err == nil {
return uint8(v), nil
}
return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
case int:
return uint8(s), nil
case int64:
return uint8(s), nil
case int32:
return uint8(s), nil
case int16:
return uint8(s), nil
case int8:
return uint8(s), nil
case uint:
return uint8(s), nil
case uint64:
return uint8(s), nil
case uint32:
return uint8(s), nil
case uint16:
return uint8(s), nil
case uint8:
return s, nil
case float64:
return uint8(s), nil
case float32:
return uint8(s), nil
case bool:
if s {
return 1, nil
}
return 0, nil
case nil:
return 0, nil
default:
return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
}
}
// From html/template/content.go // From html/template/content.go
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// indirect returns the value, after dereferencing as many times // indirect returns the value, after dereferencing as many times
@ -337,10 +697,28 @@ func ToStringE(i interface{}) (string, error) {
return strconv.FormatBool(s), nil return strconv.FormatBool(s), nil
case float64: case float64:
return strconv.FormatFloat(s, 'f', -1, 64), nil return strconv.FormatFloat(s, 'f', -1, 64), nil
case int64: case float32:
return strconv.FormatInt(s, 10), nil return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
case int: case int:
return strconv.Itoa(s), nil return strconv.Itoa(s), nil
case int64:
return strconv.FormatInt(s, 10), nil
case int32:
return strconv.Itoa(int(s)), nil
case int16:
return strconv.FormatInt(int64(s), 10), nil
case int8:
return strconv.FormatInt(int64(s), 10), nil
case uint:
return strconv.FormatInt(int64(s), 10), nil
case uint64:
return strconv.FormatInt(int64(s), 10), nil
case uint32:
return strconv.FormatInt(int64(s), 10), nil
case uint16:
return strconv.FormatInt(int64(s), 10), nil
case uint8:
return strconv.FormatInt(int64(s), 10), nil
case []byte: case []byte:
return string(s), nil return string(s), nil
case template.HTML: case template.HTML:
@ -366,7 +744,6 @@ func ToStringE(i interface{}) (string, error) {
// ToStringMapStringE casts an interface to a map[string]string type. // ToStringMapStringE casts an interface to a map[string]string type.
func ToStringMapStringE(i interface{}) (map[string]string, error) { func ToStringMapStringE(i interface{}) (map[string]string, error) {
var m = map[string]string{} var m = map[string]string{}
switch v := i.(type) { switch v := i.(type) {
@ -394,7 +771,6 @@ func ToStringMapStringE(i interface{}) (map[string]string, error) {
// ToStringMapStringSliceE casts an interface to a map[string][]string type. // ToStringMapStringSliceE casts an interface to a map[string][]string type.
func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
var m = map[string][]string{} var m = map[string][]string{}
switch v := i.(type) { switch v := i.(type) {
@ -456,7 +832,6 @@ func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
// ToStringMapBoolE casts an interface to a map[string]bool type. // ToStringMapBoolE casts an interface to a map[string]bool type.
func ToStringMapBoolE(i interface{}) (map[string]bool, error) { func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
var m = map[string]bool{} var m = map[string]bool{}
switch v := i.(type) { switch v := i.(type) {
@ -479,7 +854,6 @@ func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
// ToStringMapE casts an interface to a map[string]interface{} type. // ToStringMapE casts an interface to a map[string]interface{} type.
func ToStringMapE(i interface{}) (map[string]interface{}, error) { func ToStringMapE(i interface{}) (map[string]interface{}, error) {
var m = map[string]interface{}{} var m = map[string]interface{}{}
switch v := i.(type) { switch v := i.(type) {
@ -497,7 +871,6 @@ func ToStringMapE(i interface{}) (map[string]interface{}, error) {
// ToSliceE casts an interface to a []interface{} type. // ToSliceE casts an interface to a []interface{} type.
func ToSliceE(i interface{}) ([]interface{}, error) { func ToSliceE(i interface{}) ([]interface{}, error) {
var s []interface{} var s []interface{}
switch v := i.(type) { switch v := i.(type) {
@ -515,7 +888,6 @@ func ToSliceE(i interface{}) ([]interface{}, error) {
// ToBoolSliceE casts an interface to a []bool type. // ToBoolSliceE casts an interface to a []bool type.
func ToBoolSliceE(i interface{}) ([]bool, error) { func ToBoolSliceE(i interface{}) ([]bool, error) {
if i == nil { if i == nil {
return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i) return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
} }
@ -545,7 +917,6 @@ func ToBoolSliceE(i interface{}) ([]bool, error) {
// ToStringSliceE casts an interface to a []string type. // ToStringSliceE casts an interface to a []string type.
func ToStringSliceE(i interface{}) ([]string, error) { func ToStringSliceE(i interface{}) ([]string, error) {
var a []string var a []string
switch v := i.(type) { switch v := i.(type) {
@ -571,7 +942,6 @@ func ToStringSliceE(i interface{}) ([]string, error) {
// ToIntSliceE casts an interface to a []int type. // ToIntSliceE casts an interface to a []int type.
func ToIntSliceE(i interface{}) ([]int, error) { func ToIntSliceE(i interface{}) ([]int, error) {
if i == nil { if i == nil {
return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i) return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
} }