From 8a90f0ba78f9f439b98eec231c5bf1d7ba0749bb Mon Sep 17 00:00:00 2001 From: shockerli Date: Mon, 11 Oct 2021 20:40:22 +0800 Subject: [PATCH] feat: support interface alias type for nil --- cvte.go | 9 +++++++-- cvte_test.go | 37 ++++++++++++++++++++----------------- int.go | 4 ++++ int_test.go | 10 ++++++++++ 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/cvte.go b/cvte.go index 6a0d63f..2665a45 100644 --- a/cvte.go +++ b/cvte.go @@ -73,8 +73,13 @@ func indirect(a interface{}) (val interface{}, rt reflect.Type, rv reflect.Value val = rv.Interface() switch rt.Kind() { - case reflect.Ptr: // indirect the base type, if is be referenced many times - for rv.Kind() == reflect.Ptr && !rv.IsNil() { + case reflect.Ptr: // indirect the base type, if is been referenced many times + for rv.Kind() == reflect.Ptr { + // stop indirect until nil, avoid stack overflow + if rv.IsNil() { + val = nil + return + } rv = rv.Elem() } return indirect(rv.Interface()) diff --git a/cvte_test.go b/cvte_test.go index 73ee5ad..076851d 100644 --- a/cvte_test.go +++ b/cvte_test.go @@ -14,29 +14,28 @@ import ( // indirect type type ( - AliasTypeBool bool - AliasTypeInt int - AliasTypeInt8 int8 - AliasTypeInt16 int16 - AliasTypeInt32 int32 - AliasTypeInt64 int64 - AliasTypeUint uint - AliasTypeUint8 uint8 - AliasTypeUint16 uint16 - AliasTypeUint32 uint32 - AliasTypeUint64 uint64 - AliasTypeFloat32 float32 - AliasTypeFloat64 float64 - AliasTypeString string - AliasTypeBytes []byte + AliasTypeBool bool + AliasTypeInt int + AliasTypeInt8 int8 + AliasTypeInt16 int16 + AliasTypeInt32 int32 + AliasTypeInt64 int64 + AliasTypeUint uint + AliasTypeUint8 uint8 + AliasTypeUint16 uint16 + AliasTypeUint32 uint32 + AliasTypeUint64 uint64 + AliasTypeFloat32 float32 + AliasTypeFloat64 float64 + AliasTypeString string + AliasTypeBytes []byte + AliasTypeInterface interface{} ) var ( aliasTypeBool_true AliasTypeBool = true aliasTypeBool_false AliasTypeBool = false -) -var ( aliasTypeInt_0 AliasTypeInt = 0 aliasTypeInt_1 AliasTypeInt = 1 @@ -49,6 +48,10 @@ var ( aliasTypeString_8d15_minus AliasTypeString = "-8.15" aliasTypeString_on AliasTypeString = "on" aliasTypeString_off AliasTypeString = "off" + + pointerRunes = []rune("中国") + pointerInterNil *AliasTypeInterface + AliasTypeBytes_nil AliasTypeBytes ) // custom type diff --git a/int.go b/int.go index 62613eb..83bc636 100644 --- a/int.go +++ b/int.go @@ -332,6 +332,8 @@ func convUint64(val interface{}) (uint64, error) { // indirect type v, _, rv := indirect(val) switch vv := v.(type) { + case nil: + return 0, nil case bool: if vv { return 1, nil @@ -423,6 +425,8 @@ func convInt64(val interface{}) (int64, error) { // indirect type v, _, rv := indirect(val) switch vv := v.(type) { + case nil: + return 0, nil case bool: if vv { return 1, nil diff --git a/int_test.go b/int_test.go index a9d21df..80af942 100644 --- a/int_test.go +++ b/int_test.go @@ -1017,6 +1017,7 @@ func TestUint64E(t *testing.T) { {AliasTypeBytes("0"), 0, false}, {AliasTypeBytes("10.98"), 10, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {int(-8), 0, true}, @@ -1129,6 +1130,7 @@ func TestUint32E(t *testing.T) { {AliasTypeBytes("0"), 0, false}, {AliasTypeBytes("10.98"), 10, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {int(-8), 0, true}, @@ -1242,6 +1244,7 @@ func TestUint16E(t *testing.T) { {AliasTypeBytes("0"), 0, false}, {AliasTypeBytes("10.98"), 10, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {int(-8), 0, true}, @@ -1357,6 +1360,7 @@ func TestUint8E(t *testing.T) { {AliasTypeBytes("0"), 0, false}, {AliasTypeBytes("10.98"), 10, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {int(-8), 0, true}, @@ -1474,6 +1478,7 @@ func TestUintE(t *testing.T) { {AliasTypeBytes("0"), 0, false}, {AliasTypeBytes("10.98"), 10, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {int(-8), 0, true}, @@ -1607,6 +1612,7 @@ func TestInt64E(t *testing.T) { {aliasTypeBool_false, 0, false}, {&aliasTypeBool_false, 0, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {"10a", 0, true}, @@ -1724,6 +1730,7 @@ func TestInt32E(t *testing.T) { {aliasTypeBool_false, 0, false}, {&aliasTypeBool_false, 0, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {"10a", 0, true}, @@ -1842,6 +1849,7 @@ func TestInt16E(t *testing.T) { {aliasTypeBool_false, 0, false}, {&aliasTypeBool_false, 0, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {"10a", 0, true}, @@ -1962,6 +1970,7 @@ func TestInt8E(t *testing.T) { {aliasTypeBool_false, 0, false}, {&aliasTypeBool_false, 0, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {"10a", 0, true}, @@ -2083,6 +2092,7 @@ func TestIntE(t *testing.T) { {aliasTypeBool_false, 0, false}, {&aliasTypeBool_false, 0, false}, {json.Number("1"), 1, false}, + {pointerInterNil, 0, false}, // errors {"10a", 0, true},