From f6ea9367109119ceebf86b0aad739bf217db9a54 Mon Sep 17 00:00:00 2001 From: raghuvanshy Date: Fri, 20 Dec 2019 17:44:34 +0530 Subject: [PATCH] toIntBase10 enforces base 10 conversion --- cast.go | 6 ++++++ cast_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ caste.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 2 ++ 4 files changed, 102 insertions(+) diff --git a/cast.go b/cast.go index 9fba638..4d53c97 100644 --- a/cast.go +++ b/cast.go @@ -68,6 +68,12 @@ func ToInt(i interface{}) int { return v } +// ToIntBase10 casts an interface to an int type. +func ToIntBase10(i interface{}) int { + v, _ := ToIntEBase10(i) + return v +} + // ToUint casts an interface to a uint type. func ToUint(i interface{}) uint { v, _ := ToUintE(i) diff --git a/cast_test.go b/cast_test.go index d9a1479..8387d65 100644 --- a/cast_test.go +++ b/cast_test.go @@ -279,6 +279,52 @@ func TestToUint8E(t *testing.T) { } } +func TestToIntEBase10(t *testing.T) { + tests := []struct { + input interface{} + expect int + iserr bool + }{ + {"091", 91, false}, + {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 := ToIntEBase10(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 = ToIntBase10(test.input) + assert.Equal(t, test.expect, v, errmsg) + } +} + func TestToIntE(t *testing.T) { tests := []struct { input interface{} @@ -302,6 +348,7 @@ func TestToIntE(t *testing.T) { {"8", 8, false}, {nil, 0, false}, // errors + {"091", 0, true}, {"test", 0, true}, {testing.T{}, 0, true}, } diff --git a/caste.go b/caste.go index 70c7291..1bfb12e 100644 --- a/caste.go +++ b/caste.go @@ -369,6 +369,53 @@ func ToInt8E(i interface{}) (int8, error) { } } +// ToIntE casts an interface to an int type. +func ToIntEBase10(i interface{}) (int, error) { + i = indirect(i) + + switch s := i.(type) { + case int: + return s, nil + case int64: + return int(s), nil + case int32: + return int(s), nil + case int16: + 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, 10, 0) + if err == nil { + return int(v), nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i) + 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 int", i, i) + } +} + // ToIntE casts an interface to an int type. func ToIntE(i interface{}) (int, error) { i = indirect(i) diff --git a/go.mod b/go.mod index c1c0232..2ea106b 100644 --- a/go.mod +++ b/go.mod @@ -5,3 +5,5 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.2.2 ) + +go 1.13