From 68df522953c84529eeaf4367a8f8f89e04d92de9 Mon Sep 17 00:00:00 2001 From: shockerli Date: Tue, 9 Mar 2021 10:46:37 +0800 Subject: [PATCH] add uint/uint8/uint16/uint32/uint64 --- cvt.go | 65 +++++++ cvt_test.go | 475 +++++++++++++++++++++++++++++++++++++++++++++++++++ cvte.go | 86 ++++++++++ cvte_test.go | 423 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1049 insertions(+) diff --git a/cvt.go b/cvt.go index 4e55ad7..aff17eb 100644 --- a/cvt.go +++ b/cvt.go @@ -12,3 +12,68 @@ func Bool(v interface{}, def ...bool) bool { return false } + +// Uint64 convert an interface to a uint64 type, with default value +func Uint64(v interface{}, def ...uint64) uint64 { + if v, err := Uint64E(v); err == nil { + return v + } + + if len(def) > 0 { + return def[0] + } + + return 0 +} + +// Uint32 convert an interface to a uint32 type, with default value +func Uint32(v interface{}, def ...uint32) uint32 { + if v, err := Uint32E(v); err == nil { + return v + } + + if len(def) > 0 { + return def[0] + } + + return 0 +} + +// Uint16 convert an interface to a uint16 type, with default value +func Uint16(v interface{}, def ...uint16) uint16 { + if v, err := Uint16E(v); err == nil { + return v + } + + if len(def) > 0 { + return def[0] + } + + return 0 +} + +// Uint8 convert an interface to a uint8 type, with default value +func Uint8(v interface{}, def ...uint8) uint8 { + if v, err := Uint8E(v); err == nil { + return v + } + + if len(def) > 0 { + return def[0] + } + + return 0 +} + +// Uint convert an interface to a uint type, with default value +func Uint(v interface{}, def ...uint) uint { + if v, err := UintE(v); err == nil { + return v + } + + if len(def) > 0 { + return def[0] + } + + return 0 +} diff --git a/cvt_test.go b/cvt_test.go index 55028ef..1db5ff0 100644 --- a/cvt_test.go +++ b/cvt_test.go @@ -111,3 +111,478 @@ func TestBool_BaseLine(t *testing.T) { assert.Equal(t, tt.expect, v, msg) } } + +func TestUint64_HasDefault(t *testing.T) { + tests := []struct { + input interface{} + def uint64 + expect uint64 + }{ + // supported value, def is not used, def != expect + {int(8), 1, 8}, + {int8(8), 1, 8}, + {int16(8), 1, 8}, + {int32(8), 1, 8}, + {int64(8), 1, 8}, + {uint(8), 1, 8}, + {uint8(8), 1, 8}, + {uint16(8), 1, 8}, + {uint32(8), 1, 8}, + {uint64(8), 1, 8}, + {float32(8.31), 1, 8}, + {float64(8.31), 1, 8}, + {true, 2, 1}, + {false, 2, 0}, + {"8", 2, 8}, + {"8.00", 2, 8}, + {"8.01", 2, 8}, + {nil, 2, 0}, + {aliasTypeInt_0, 2, 0}, + {&aliasTypeInt_0, 2, 0}, + {aliasTypeInt_1, 2, 1}, + {&aliasTypeInt_1, 2, 1}, + {aliasTypeString_0, 2, 0}, + {&aliasTypeString_0, 2, 0}, + {aliasTypeString_1, 2, 1}, + {&aliasTypeString_1, 2, 1}, + {aliasTypeString_8d15, 2, 8}, + {&aliasTypeString_8d15, 2, 8}, + + // unsupported value, def == expect + {int(-8), 1, 1}, + {int8(-8), 1, 1}, + {int16(-8), 1, 1}, + {int32(-8), 1, 1}, + {int64(-8), 1, 1}, + {float32(-8.31), 1, 1}, + {float64(-8.31), 1, 1}, + {"-8", 1, 1}, + {"-8.01", 1, 1}, + {"10a", 1, 1}, + {"a10a", 1, 1}, + {"8.01a", 1, 1}, + {"8.01 ", 1, 1}, + {"hello", 1, 1}, + {testing.T{}, 1, 1}, + {&testing.T{}, 1, 1}, + {[]int{}, 1, 1}, + {[]string{}, 1, 1}, + {[...]string{}, 1, 1}, + {map[int]string{}, 1, 1}, + {aliasTypeString_8d15_minus, 1, 1}, + {&aliasTypeString_8d15_minus, 1, 1}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], def[%+v], expect[%+v]", i, tt.input, tt.def, tt.expect) + + v := cvt.Uint64(tt.input, tt.def) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint64_BaseLine(t *testing.T) { + tests := []struct { + input interface{} + expect uint64 + }{ + {testing.T{}, 0}, + {&testing.T{}, 0}, + {[]int{}, 0}, + {[]int{1, 2, 3}, 0}, + {[]string{}, 0}, + {[]string{"a", "b", "c"}, 0}, + {[...]string{}, 0}, + {map[int]string{}, 0}, + {aliasTypeString_8d15_minus, 0}, + {&aliasTypeString_8d15_minus, 0}, + {"4873546382743564386435354655456575456754356765546554643456", 0}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v]", i, tt.input, tt.expect) + + v := cvt.Uint64(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint32_HasDefault(t *testing.T) { + tests := []struct { + input interface{} + def uint32 + expect uint32 + }{ + // supported value, def is not used, def != expect + {int(8), 1, 8}, + {int8(8), 1, 8}, + {int16(8), 1, 8}, + {int32(8), 1, 8}, + {int64(8), 1, 8}, + {uint(8), 1, 8}, + {uint8(8), 1, 8}, + {uint16(8), 1, 8}, + {uint32(8), 1, 8}, + {uint64(8), 1, 8}, + {float32(8.31), 1, 8}, + {float64(8.31), 1, 8}, + {true, 2, 1}, + {false, 2, 0}, + {"8", 2, 8}, + {"8.00", 2, 8}, + {"8.01", 2, 8}, + {nil, 2, 0}, + {aliasTypeInt_0, 2, 0}, + {&aliasTypeInt_0, 2, 0}, + {aliasTypeInt_1, 2, 1}, + {&aliasTypeInt_1, 2, 1}, + {aliasTypeString_0, 2, 0}, + {&aliasTypeString_0, 2, 0}, + {aliasTypeString_1, 2, 1}, + {&aliasTypeString_1, 2, 1}, + {aliasTypeString_8d15, 2, 8}, + {&aliasTypeString_8d15, 2, 8}, + + // unsupported value, def == expect + {int(-8), 1, 1}, + {int8(-8), 1, 1}, + {int16(-8), 1, 1}, + {int32(-8), 1, 1}, + {int64(-8), 1, 1}, + {float32(-8.31), 1, 1}, + {float64(-8.31), 1, 1}, + {"-8", 1, 1}, + {"-8.01", 1, 1}, + {"10a", 1, 1}, + {"a10a", 1, 1}, + {"8.01a", 1, 1}, + {"8.01 ", 1, 1}, + {"hello", 1, 1}, + {testing.T{}, 1, 1}, + {&testing.T{}, 1, 1}, + {[]int{}, 1, 1}, + {[]string{}, 1, 1}, + {[...]string{}, 1, 1}, + {map[int]string{}, 1, 1}, + {aliasTypeString_8d15_minus, 1, 1}, + {&aliasTypeString_8d15_minus, 1, 1}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], def[%+v], expect[%+v]", i, tt.input, tt.def, tt.expect) + + v := cvt.Uint32(tt.input, tt.def) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint32_BaseLine(t *testing.T) { + tests := []struct { + input interface{} + expect uint32 + }{ + {testing.T{}, 0}, + {&testing.T{}, 0}, + {[]int{}, 0}, + {[]int{1, 2, 3}, 0}, + {[]string{}, 0}, + {[]string{"a", "b", "c"}, 0}, + {[...]string{}, 0}, + {map[int]string{}, 0}, + {aliasTypeString_8d15_minus, 0}, + {&aliasTypeString_8d15_minus, 0}, + {"4873546382743564386435354655456575456754356765546554643456", 0}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v]", i, tt.input, tt.expect) + + v := cvt.Uint32(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint16_HasDefault(t *testing.T) { + tests := []struct { + input interface{} + def uint16 + expect uint16 + }{ + // supported value, def is not used, def != expect + {int(8), 1, 8}, + {int8(8), 1, 8}, + {int16(8), 1, 8}, + {int32(8), 1, 8}, + {int64(8), 1, 8}, + {uint(8), 1, 8}, + {uint8(8), 1, 8}, + {uint16(8), 1, 8}, + {uint32(8), 1, 8}, + {uint64(8), 1, 8}, + {float32(8.31), 1, 8}, + {float64(8.31), 1, 8}, + {true, 2, 1}, + {false, 2, 0}, + {"8", 2, 8}, + {"8.00", 2, 8}, + {"8.01", 2, 8}, + {nil, 2, 0}, + {aliasTypeInt_0, 2, 0}, + {&aliasTypeInt_0, 2, 0}, + {aliasTypeInt_1, 2, 1}, + {&aliasTypeInt_1, 2, 1}, + {aliasTypeString_0, 2, 0}, + {&aliasTypeString_0, 2, 0}, + {aliasTypeString_1, 2, 1}, + {&aliasTypeString_1, 2, 1}, + {aliasTypeString_8d15, 2, 8}, + {&aliasTypeString_8d15, 2, 8}, + + // unsupported value, def == expect + {int(-8), 1, 1}, + {int8(-8), 1, 1}, + {int16(-8), 1, 1}, + {int32(-8), 1, 1}, + {int64(-8), 1, 1}, + {float32(-8.31), 1, 1}, + {float64(-8.31), 1, 1}, + {"-8", 1, 1}, + {"-8.01", 1, 1}, + {"10a", 1, 1}, + {"a10a", 1, 1}, + {"8.01a", 1, 1}, + {"8.01 ", 1, 1}, + {"hello", 1, 1}, + {testing.T{}, 1, 1}, + {&testing.T{}, 1, 1}, + {[]int{}, 1, 1}, + {[]string{}, 1, 1}, + {[...]string{}, 1, 1}, + {map[int]string{}, 1, 1}, + {aliasTypeString_8d15_minus, 1, 1}, + {&aliasTypeString_8d15_minus, 1, 1}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], def[%+v], expect[%+v]", i, tt.input, tt.def, tt.expect) + + v := cvt.Uint16(tt.input, tt.def) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint16_BaseLine(t *testing.T) { + tests := []struct { + input interface{} + expect uint16 + }{ + {testing.T{}, 0}, + {&testing.T{}, 0}, + {[]int{}, 0}, + {[]int{1, 2, 3}, 0}, + {[]string{}, 0}, + {[]string{"a", "b", "c"}, 0}, + {[...]string{}, 0}, + {map[int]string{}, 0}, + {aliasTypeString_8d15_minus, 0}, + {&aliasTypeString_8d15_minus, 0}, + {"4873546382743564386435354655456575456754356765546554643456", 0}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v]", i, tt.input, tt.expect) + + v := cvt.Uint16(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint8_HasDefault(t *testing.T) { + tests := []struct { + input interface{} + def uint8 + expect uint8 + }{ + // supported value, def is not used, def != expect + {int(8), 1, 8}, + {int8(8), 1, 8}, + {int16(8), 1, 8}, + {int32(8), 1, 8}, + {int64(8), 1, 8}, + {uint(8), 1, 8}, + {uint8(8), 1, 8}, + {uint16(8), 1, 8}, + {uint32(8), 1, 8}, + {uint64(8), 1, 8}, + {float32(8.31), 1, 8}, + {float64(8.31), 1, 8}, + {true, 2, 1}, + {false, 2, 0}, + {"8", 2, 8}, + {"8.00", 2, 8}, + {"8.01", 2, 8}, + {nil, 2, 0}, + {aliasTypeInt_0, 2, 0}, + {&aliasTypeInt_0, 2, 0}, + {aliasTypeInt_1, 2, 1}, + {&aliasTypeInt_1, 2, 1}, + {aliasTypeString_0, 2, 0}, + {&aliasTypeString_0, 2, 0}, + {aliasTypeString_1, 2, 1}, + {&aliasTypeString_1, 2, 1}, + {aliasTypeString_8d15, 2, 8}, + {&aliasTypeString_8d15, 2, 8}, + + // unsupported value, def == expect + {int(-8), 1, 1}, + {int8(-8), 1, 1}, + {int16(-8), 1, 1}, + {int32(-8), 1, 1}, + {int64(-8), 1, 1}, + {float32(-8.31), 1, 1}, + {float64(-8.31), 1, 1}, + {"-8", 1, 1}, + {"-8.01", 1, 1}, + {"10a", 1, 1}, + {"a10a", 1, 1}, + {"8.01a", 1, 1}, + {"8.01 ", 1, 1}, + {"hello", 1, 1}, + {testing.T{}, 1, 1}, + {&testing.T{}, 1, 1}, + {[]int{}, 1, 1}, + {[]string{}, 1, 1}, + {[...]string{}, 1, 1}, + {map[int]string{}, 1, 1}, + {aliasTypeString_8d15_minus, 1, 1}, + {&aliasTypeString_8d15_minus, 1, 1}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], def[%+v], expect[%+v]", i, tt.input, tt.def, tt.expect) + + v := cvt.Uint8(tt.input, tt.def) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint8_BaseLine(t *testing.T) { + tests := []struct { + input interface{} + expect uint8 + }{ + {testing.T{}, 0}, + {&testing.T{}, 0}, + {[]int{}, 0}, + {[]int{1, 2, 3}, 0}, + {[]string{}, 0}, + {[]string{"a", "b", "c"}, 0}, + {[...]string{}, 0}, + {map[int]string{}, 0}, + {aliasTypeString_8d15_minus, 0}, + {&aliasTypeString_8d15_minus, 0}, + {"4873546382743564386435354655456575456754356765546554643456", 0}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v]", i, tt.input, tt.expect) + + v := cvt.Uint8(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint_HasDefault(t *testing.T) { + tests := []struct { + input interface{} + def uint + expect uint + }{ + // supported value, def is not used, def != expect + {int(8), 1, 8}, + {int8(8), 1, 8}, + {int16(8), 1, 8}, + {int32(8), 1, 8}, + {int64(8), 1, 8}, + {uint(8), 1, 8}, + {uint8(8), 1, 8}, + {uint16(8), 1, 8}, + {uint32(8), 1, 8}, + {uint64(8), 1, 8}, + {float32(8.31), 1, 8}, + {float64(8.31), 1, 8}, + {true, 2, 1}, + {false, 2, 0}, + {"8", 2, 8}, + {"8.00", 2, 8}, + {"8.01", 2, 8}, + {nil, 2, 0}, + {aliasTypeInt_0, 2, 0}, + {&aliasTypeInt_0, 2, 0}, + {aliasTypeInt_1, 2, 1}, + {&aliasTypeInt_1, 2, 1}, + {aliasTypeString_0, 2, 0}, + {&aliasTypeString_0, 2, 0}, + {aliasTypeString_1, 2, 1}, + {&aliasTypeString_1, 2, 1}, + {aliasTypeString_8d15, 2, 8}, + {&aliasTypeString_8d15, 2, 8}, + + // unsupported value, def == expect + {int(-8), 1, 1}, + {int8(-8), 1, 1}, + {int16(-8), 1, 1}, + {int32(-8), 1, 1}, + {int64(-8), 1, 1}, + {float32(-8.31), 1, 1}, + {float64(-8.31), 1, 1}, + {"-8", 1, 1}, + {"-8.01", 1, 1}, + {"10a", 1, 1}, + {"a10a", 1, 1}, + {"8.01a", 1, 1}, + {"8.01 ", 1, 1}, + {"hello", 1, 1}, + {testing.T{}, 1, 1}, + {&testing.T{}, 1, 1}, + {[]int{}, 1, 1}, + {[]string{}, 1, 1}, + {[...]string{}, 1, 1}, + {map[int]string{}, 1, 1}, + {aliasTypeString_8d15_minus, 1, 1}, + {&aliasTypeString_8d15_minus, 1, 1}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], def[%+v], expect[%+v]", i, tt.input, tt.def, tt.expect) + + v := cvt.Uint(tt.input, tt.def) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint_BaseLine(t *testing.T) { + tests := []struct { + input interface{} + expect uint + }{ + {testing.T{}, 0}, + {&testing.T{}, 0}, + {[]int{}, 0}, + {[]int{1, 2, 3}, 0}, + {[]string{}, 0}, + {[]string{"a", "b", "c"}, 0}, + {[...]string{}, 0}, + {map[int]string{}, 0}, + {aliasTypeString_8d15_minus, 0}, + {&aliasTypeString_8d15_minus, 0}, + {"4873546382743564386435354655456575456754356765546554643456", 0}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v]", i, tt.input, tt.expect) + + v := cvt.Uint(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} diff --git a/cvte.go b/cvte.go index 0017f14..8763fd3 100644 --- a/cvte.go +++ b/cvte.go @@ -2,6 +2,7 @@ package cvt import ( "fmt" + "math" "reflect" "strconv" "strings" @@ -55,6 +56,91 @@ func str2bool(str string) (bool, error) { } } +// Uint64E convert an interface to a uint64 type +func Uint64E(val interface{}) (uint64, error) { + e := err(val, "uint64") + v, _, rv := Indirect(val) + + switch vv := v.(type) { + case nil: + return 0, nil + case bool: + if vv { + return 1, nil + } + return 0, nil + case string: + vvv, err := strconv.ParseFloat(vv, 64) + if err == nil && vvv >= 0 && vvv <= math.MaxUint64 { + return uint64(math.Floor(vvv)), nil + } + case uint, uint8, uint16, uint32, uint64: + return rv.Uint(), nil + case int, int8, int16, int32, int64: + if rv.Int() >= 0 { + return uint64(rv.Int()), nil + } + case float32, float64: + if rv.Float() >= 0 && rv.Float() <= math.MaxUint64 { + return uint64(math.Floor(rv.Float())), nil + } + } + + return 0, e +} + +// Uint32E convert an interface to a uint32 type +func Uint32E(val interface{}) (uint32, error) { + v, e := Uint64E(val) + if e != nil { + return 0, err(val, "uint32") + } + if v > math.MaxUint32 { + return 0, fmt.Errorf("%w, out of max limit value(%d)", err(val, "uint32"), math.MaxUint32) + } + + return uint32(v), nil +} + +// Uint16E convert an interface to a uint16 type +func Uint16E(val interface{}) (uint16, error) { + v, e := Uint64E(val) + if e != nil { + return 0, err(val, "uint16") + } + if v > math.MaxUint16 { + return 0, fmt.Errorf("%w, out of max limit value(%d)", err(val, "uint16"), math.MaxUint16) + } + + return uint16(v), nil +} + +// Uint8E convert an interface to a uint8 type +func Uint8E(val interface{}) (uint8, error) { + v, e := Uint64E(val) + if e != nil { + return 0, err(val, "uint8") + } + if v > math.MaxUint8 { + return 0, fmt.Errorf("%w, out of max limit value(%d)", err(val, "uint8"), math.MaxUint8) + } + + return uint8(v), nil +} + +// UintE convert an interface to a uint type +func UintE(val interface{}) (uint, error) { + v, e := Uint64E(val) + if e != nil { + return 0, err(val, "uint") + } + if v > uint64(^uint(0)) { + return 0, fmt.Errorf("%w, out of max limit value(%d)", err(val, "uint"), ^uint(0)) + } + + return uint(v), nil +} + // Indirect returns the value with base type func Indirect(a interface{}) (val interface{}, k reflect.Kind, v reflect.Value) { if a == nil { diff --git a/cvte_test.go b/cvte_test.go index 27daa90..0a6883d 100644 --- a/cvte_test.go +++ b/cvte_test.go @@ -2,6 +2,7 @@ package cvt_test import ( "fmt" + "math" "testing" "github.com/stretchr/testify/assert" @@ -119,3 +120,425 @@ func TestBoolE(t *testing.T) { assert.Equal(t, tt.expect, v, msg) } } + +func TestUint64E(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}, + {int64(1487354638276643554), 1487354638276643554, false}, + {uint(8), 8, false}, + {uint8(8), 8, false}, + {uint16(8), 8, false}, + {uint32(8), 8, false}, + {uint64(8), 8, false}, + {uint64(1487354638276643554), 1487354638276643554, false}, + {uint(math.MaxUint32), uint64(math.MaxUint32), false}, + {uint32(math.MaxUint32), uint64(math.MaxUint32), false}, + {uint64(math.MaxUint64), uint64(math.MaxUint64), false}, + {float32(8.31), 8, false}, + {float64(8.31), 8, false}, + {true, 1, false}, + {false, 0, false}, + {"8", 8, false}, + {"8.00", 8, false}, + {"8.01", 8, false}, + {nil, 0, false}, + {aliasTypeInt_0, 0, false}, + {&aliasTypeInt_0, 0, false}, + {aliasTypeInt_1, 1, false}, + {&aliasTypeInt_1, 1, false}, + {aliasTypeString_0, 0, false}, + {&aliasTypeString_0, 0, false}, + {aliasTypeString_1, 1, false}, + {&aliasTypeString_1, 1, false}, + {aliasTypeString_8d15, 8, false}, + {&aliasTypeString_8d15, 8, false}, + + // errors + {int(-8), 0, true}, + {int8(-8), 0, true}, + {int16(-8), 0, true}, + {int32(-8), 0, true}, + {int64(-8), 0, true}, + {float32(-8.31), 0, true}, + {float64(-8.31), 0, true}, + {"-8", 0, true}, + {"-8.01", 0, true}, + {"10a", 0, true}, + {"a10a", 0, true}, + {"8.01a", 0, true}, + {"8.01 ", 0, true}, + {"4873546382743564386435354655456575456754356765546554643456", 0, true}, + {float64(4873546382743564386435354655456575456754356765546554643456), 0, true}, + {"hello", 0, true}, + {testing.T{}, 0, true}, + {&testing.T{}, 0, true}, + {[]int{}, 0, true}, + {[]string{}, 0, true}, + {[...]string{}, 0, true}, + {map[int]string{}, 0, true}, + {aliasTypeString_8d15_minus, 0, true}, + {&aliasTypeString_8d15_minus, 0, true}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v], isErr[%+v]", i, tt.input, tt.expect, tt.isErr) + + v, err := cvt.Uint64E(tt.input) + if tt.isErr { + assert.Error(t, err, msg) + continue + } + + assert.NoError(t, err, msg) + assert.Equal(t, tt.expect, v, msg) + + // Non-E test with no default value: + v = cvt.Uint64(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint32E(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}, + {uint(math.MaxUint32), uint32(math.MaxUint32), false}, + {uint32(math.MaxUint32), uint32(math.MaxUint32), false}, + {float32(8.31), 8, false}, + {float64(8.31), 8, false}, + {true, 1, false}, + {false, 0, false}, + {"8", 8, false}, + {"8.00", 8, false}, + {"8.01", 8, false}, + {nil, 0, false}, + {aliasTypeInt_0, 0, false}, + {&aliasTypeInt_0, 0, false}, + {aliasTypeInt_1, 1, false}, + {&aliasTypeInt_1, 1, false}, + {aliasTypeString_0, 0, false}, + {&aliasTypeString_0, 0, false}, + {aliasTypeString_1, 1, false}, + {&aliasTypeString_1, 1, false}, + {aliasTypeString_8d15, 8, false}, + {&aliasTypeString_8d15, 8, false}, + + // errors + {int(-8), 0, true}, + {int8(-8), 0, true}, + {int16(-8), 0, true}, + {int32(-8), 0, true}, + {int64(-8), 0, true}, + {float32(-8.31), 0, true}, + {float64(-8.31), 0, true}, + {"-8", 0, true}, + {"-8.01", 0, true}, + {"10a", 0, true}, + {"a10a", 0, true}, + {"8.01a", 0, true}, + {"8.01 ", 0, true}, + {"4873546382743564386435354655456575456754356765546554643456", 0, true}, + {float64(4873546382743564386435354655456575456754356765546554643456), 0, true}, + {uint64(math.MaxUint64), 0, true}, + {int64(1487354638276643554), 0, true}, + {uint64(1487354638276643554), 0, true}, + {"hello", 0, true}, + {testing.T{}, 0, true}, + {&testing.T{}, 0, true}, + {[]int{}, 0, true}, + {[]string{}, 0, true}, + {[...]string{}, 0, true}, + {map[int]string{}, 0, true}, + {aliasTypeString_8d15_minus, 0, true}, + {&aliasTypeString_8d15_minus, 0, true}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v], isErr[%+v]", i, tt.input, tt.expect, tt.isErr) + + v, err := cvt.Uint32E(tt.input) + if tt.isErr { + assert.Error(t, err, msg) + continue + } + + assert.NoError(t, err, msg) + assert.Equal(t, tt.expect, v, msg) + + // Non-E test with no default value: + v = cvt.Uint32(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint16E(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}, + {"8.00", 8, false}, + {"8.01", 8, false}, + {nil, 0, false}, + {aliasTypeInt_0, 0, false}, + {&aliasTypeInt_0, 0, false}, + {aliasTypeInt_1, 1, false}, + {&aliasTypeInt_1, 1, false}, + {aliasTypeString_0, 0, false}, + {&aliasTypeString_0, 0, false}, + {aliasTypeString_1, 1, false}, + {&aliasTypeString_1, 1, false}, + {aliasTypeString_8d15, 8, false}, + {&aliasTypeString_8d15, 8, false}, + + // errors + {int(-8), 0, true}, + {int8(-8), 0, true}, + {int16(-8), 0, true}, + {int32(-8), 0, true}, + {int64(-8), 0, true}, + {float32(-8.31), 0, true}, + {float64(-8.31), 0, true}, + {"-8", 0, true}, + {"-8.01", 0, true}, + {"10a", 0, true}, + {"a10a", 0, true}, + {"8.01a", 0, true}, + {"8.01 ", 0, true}, + {"4873546382743564386435354655456575456754356765546554643456", 0, true}, + {float64(4873546382743564386435354655456575456754356765546554643456), 0, true}, + {uint64(math.MaxUint64), 0, true}, + {int64(1487354638276643554), 0, true}, + {uint64(1487354638276643554), 0, true}, + {uint(math.MaxUint32), 0, true}, + {uint32(math.MaxUint32), 0, true}, + {"hello", 0, true}, + {testing.T{}, 0, true}, + {&testing.T{}, 0, true}, + {[]int{}, 0, true}, + {[]string{}, 0, true}, + {[...]string{}, 0, true}, + {map[int]string{}, 0, true}, + {aliasTypeString_8d15_minus, 0, true}, + {&aliasTypeString_8d15_minus, 0, true}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v], isErr[%+v]", i, tt.input, tt.expect, tt.isErr) + + v, err := cvt.Uint16E(tt.input) + if tt.isErr { + assert.Error(t, err, msg) + continue + } + + assert.NoError(t, err, msg) + assert.Equal(t, tt.expect, v, msg) + + // Non-E test with no default value: + v = cvt.Uint16(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUint8E(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}, + {"8.00", 8, false}, + {"8.01", 8, false}, + {nil, 0, false}, + {aliasTypeInt_0, 0, false}, + {&aliasTypeInt_0, 0, false}, + {aliasTypeInt_1, 1, false}, + {&aliasTypeInt_1, 1, false}, + {aliasTypeString_0, 0, false}, + {&aliasTypeString_0, 0, false}, + {aliasTypeString_1, 1, false}, + {&aliasTypeString_1, 1, false}, + {aliasTypeString_8d15, 8, false}, + {&aliasTypeString_8d15, 8, false}, + + // errors + {int(-8), 0, true}, + {int8(-8), 0, true}, + {int16(-8), 0, true}, + {int32(-8), 0, true}, + {int64(-8), 0, true}, + {float32(-8.31), 0, true}, + {float64(-8.31), 0, true}, + {"-8", 0, true}, + {"-8.01", 0, true}, + {"10a", 0, true}, + {"a10a", 0, true}, + {"8.01a", 0, true}, + {"8.01 ", 0, true}, + {"4873546382743564386435354655456575456754356765546554643456", 0, true}, + {float64(4873546382743564386435354655456575456754356765546554643456), 0, true}, + {uint64(math.MaxUint64), 0, true}, + {int64(1487354638276643554), 0, true}, + {uint64(1487354638276643554), 0, true}, + {uint(math.MaxUint32), 0, true}, + {uint32(math.MaxUint32), 0, true}, + {"hello", 0, true}, + {testing.T{}, 0, true}, + {&testing.T{}, 0, true}, + {[]int{}, 0, true}, + {[]string{}, 0, true}, + {[...]string{}, 0, true}, + {map[int]string{}, 0, true}, + {aliasTypeString_8d15_minus, 0, true}, + {&aliasTypeString_8d15_minus, 0, true}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%+v], isErr[%+v]", i, tt.input, tt.expect, tt.isErr) + + v, err := cvt.Uint8E(tt.input) + if tt.isErr { + assert.Error(t, err, msg) + continue + } + + assert.NoError(t, err, msg) + assert.Equal(t, tt.expect, v, msg) + + // Non-E test with no default value: + v = cvt.Uint8(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +} + +func TestUintE(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}, + {"8.00", 8, false}, + {"8.01", 8, false}, + {uint64(math.MaxUint64), uint(math.MaxUint64), false}, + {uint32(math.MaxUint32), uint(math.MaxUint32), false}, + {nil, 0, false}, + {aliasTypeInt_0, 0, false}, + {&aliasTypeInt_0, 0, false}, + {aliasTypeInt_1, 1, false}, + {&aliasTypeInt_1, 1, false}, + {aliasTypeString_0, 0, false}, + {&aliasTypeString_0, 0, false}, + {aliasTypeString_1, 1, false}, + {&aliasTypeString_1, 1, false}, + {aliasTypeString_8d15, 8, false}, + {&aliasTypeString_8d15, 8, false}, + + // errors + {int(-8), 0, true}, + {int8(-8), 0, true}, + {int16(-8), 0, true}, + {int32(-8), 0, true}, + {int64(-8), 0, true}, + {float32(-8.31), 0, true}, + {float64(-8.31), 0, true}, + {"-8", 0, true}, + {"-8.01", 0, true}, + {"10a", 0, true}, + {"a10a", 0, true}, + {"8.01a", 0, true}, + {"8.01 ", 0, true}, + {"4873546382743564386435354655456575456754356765546554643456", 0, true}, + {float64(4873546382743564386435354655456575456754356765546554643456), 0, true}, + {"hello", 0, true}, + {testing.T{}, 0, true}, + {&testing.T{}, 0, true}, + {[]int{}, 0, true}, + {[]string{}, 0, true}, + {[...]string{}, 0, true}, + {map[int]string{}, 0, true}, + {aliasTypeString_8d15_minus, 0, true}, + {&aliasTypeString_8d15_minus, 0, true}, + } + + for i, tt := range tests { + msg := fmt.Sprintf("i = %d, input[%+v], expect[%v], isErr[%v]", i, tt.input, tt.expect, tt.isErr) + + v, err := cvt.UintE(tt.input) + if tt.isErr { + assert.Error(t, err, msg) + continue + } + + assert.NoError(t, err, msg) + assert.Equal(t, tt.expect, v, msg) + + // Non-E test with no default value: + v = cvt.Uint(tt.input) + assert.Equal(t, tt.expect, v, msg) + } +}