diff --git a/cast.go b/cast.go index 8d318b6..dc504b4 100644 --- a/cast.go +++ b/cast.go @@ -32,6 +32,12 @@ func ToFloat64(i interface{}) float64 { 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. func ToInt64(i interface{}) int64 { v, _ := ToInt64E(i) @@ -62,6 +68,36 @@ func ToInt(i interface{}) int { 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. func ToString(i interface{}) string { v, _ := ToStringE(i) diff --git a/cast_test.go b/cast_test.go index a5672fa..8e964fb 100644 --- a/cast_test.go +++ b/cast_test.go @@ -14,6 +14,231 @@ import ( "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) { tests := []struct { input interface{} @@ -25,6 +250,12 @@ func TestToIntE(t *testing.T) { {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}, @@ -64,6 +295,12 @@ func TestToInt64E(t *testing.T) { {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}, @@ -103,6 +340,12 @@ func TestToInt32E(t *testing.T) { {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}, @@ -142,6 +385,12 @@ func TestToInt16E(t *testing.T) { {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}, @@ -181,6 +430,12 @@ func TestToInt8E(t *testing.T) { {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}, @@ -220,9 +475,16 @@ func TestToFloat64E(t *testing.T) { {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), 8, false}, {float64(8.31), 8.31, false}, {"8", 8, false}, + {true, 1, false}, + {false, 0, false}, // errors {"test", 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) { type Key struct { k string @@ -258,7 +564,16 @@ func TestToStringE(t *testing.T) { 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}, {true, "true", 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}, {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}, + {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}, // errors {"2006", time.Time{}, true}, @@ -754,7 +1072,13 @@ func TestToDurationE(t *testing.T) { {int32(5), td, false}, {int16(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}, + {float32(5), td, false}, {string("5"), td, false}, {string("5ns"), td, false}, {string("5us"), time.Microsecond * td, false}, diff --git a/caste.go b/caste.go index d7e0f9c..79e6ae4 100644 --- a/caste.go +++ b/caste.go @@ -25,10 +25,16 @@ func ToTimeE(i interface{}) (tim time.Time, err error) { return StringToDate(v) case int: return time.Unix(int64(v), 0), nil - case int32: - return time.Unix(int64(v), 0), nil case int64: 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: 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) { case time.Duration: 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)) return case float32, float64: @@ -62,7 +68,6 @@ func ToDurationE(i interface{}) (d time.Duration, err error) { // ToBoolE casts an interface to a bool type. func ToBoolE(i interface{}) (bool, error) { - i = indirect(i) switch b := i.(type) { @@ -91,6 +96,8 @@ func ToFloat64E(i interface{}) (float64, error) { return s, nil case float32: return float64(s), nil + case int: + return float64(s), nil case int64: return float64(s), nil case int32: @@ -99,16 +106,74 @@ func ToFloat64E(i interface{}) (float64, error) { return float64(s), nil case int8: 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 case string: v, err := strconv.ParseFloat(s, 64) if err == 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: - 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) switch s := i.(type) { - case int64: - return s, nil case int: return int64(s), nil + case int64: + return s, nil case int32: return int64(s), nil case int16: return int64(s), nil case int8: 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: v, err := strconv.ParseInt(s, 0, 0) if err == nil { return v, nil } return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i) - case float64: - return int64(s), nil case bool: if bool(s) { return int64(1), nil @@ -152,24 +229,36 @@ func ToInt32E(i interface{}) (int32, error) { i = indirect(i) switch s := i.(type) { - case int64: - return int32(s), nil case int: return int32(s), nil + case int64: + return int32(s), nil case int32: return s, nil case int16: return int32(s), nil case int8: 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: v, err := strconv.ParseInt(s, 0, 0) if err == nil { return int32(v), nil } return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i) - case float64: - return int32(s), nil case bool: if bool(s) { return int32(1), nil @@ -187,24 +276,36 @@ func ToInt16E(i interface{}) (int16, error) { i = indirect(i) switch s := i.(type) { - case int64: - return int16(s), nil case int: return int16(s), nil + case int64: + return int16(s), nil case int32: return int16(s), nil case int16: return s, nil case int8: 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: v, err := strconv.ParseInt(s, 0, 0) if err == nil { return int16(v), nil } return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i) - case float64: - return int16(s), nil case bool: if bool(s) { return int16(1), nil @@ -222,24 +323,36 @@ func ToInt8E(i interface{}) (int8, error) { i = indirect(i) switch s := i.(type) { - case int64: - return int8(s), nil case int: return int8(s), nil + case int64: + return int8(s), nil case int32: return int8(s), nil case int16: return int8(s), nil case int8: 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: v, err := strconv.ParseInt(s, 0, 0) if err == nil { return int8(v), nil } return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i) - case float64: - return int8(s), nil case bool: if bool(s) { return int8(1), nil @@ -267,14 +380,26 @@ func ToIntE(i interface{}) (int, error) { return int(s), nil case int8: 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: v, err := strconv.ParseInt(s, 0, 0) if err == nil { return int(v), nil } return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i) - case float64: - return int(s), nil case bool: if bool(s) { 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 // Copyright 2011 The Go Authors. All rights reserved. // indirect returns the value, after dereferencing as many times @@ -337,10 +697,28 @@ func ToStringE(i interface{}) (string, error) { return strconv.FormatBool(s), nil case float64: return strconv.FormatFloat(s, 'f', -1, 64), nil - case int64: - return strconv.FormatInt(s, 10), nil + case float32: + return strconv.FormatFloat(float64(s), 'f', -1, 32), nil case int: 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: return string(s), nil case template.HTML: @@ -366,7 +744,6 @@ func ToStringE(i interface{}) (string, error) { // ToStringMapStringE casts an interface to a map[string]string type. func ToStringMapStringE(i interface{}) (map[string]string, error) { - var m = map[string]string{} 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. func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { - var m = map[string][]string{} 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. func ToStringMapBoolE(i interface{}) (map[string]bool, error) { - var m = map[string]bool{} 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. func ToStringMapE(i interface{}) (map[string]interface{}, error) { - var m = map[string]interface{}{} switch v := i.(type) { @@ -497,7 +871,6 @@ func ToStringMapE(i interface{}) (map[string]interface{}, error) { // ToSliceE casts an interface to a []interface{} type. func ToSliceE(i interface{}) ([]interface{}, error) { - var s []interface{} switch v := i.(type) { @@ -515,7 +888,6 @@ func ToSliceE(i interface{}) ([]interface{}, error) { // ToBoolSliceE casts an interface to a []bool type. func ToBoolSliceE(i interface{}) ([]bool, error) { - if i == nil { 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. func ToStringSliceE(i interface{}) ([]string, error) { - var a []string switch v := i.(type) { @@ -571,7 +942,6 @@ func ToStringSliceE(i interface{}) ([]string, error) { // ToIntSliceE casts an interface to a []int type. func ToIntSliceE(i interface{}) ([]int, error) { - if i == nil { return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i) }