From 551ceef0e14c1f428bb577f372f03792b91c670e Mon Sep 17 00:00:00 2001 From: John Guo Date: Fri, 19 Nov 2021 15:21:46 +0800 Subject: [PATCH] improve package gconv --- util/gconv/gconv.go | 314 +++----------------------------------- util/gconv/gconv_float.go | 55 +++++++ util/gconv/gconv_int.go | 138 +++++++++++++++++ util/gconv/gconv_uint.go | 120 +++++++++++++++ 4 files changed, 330 insertions(+), 297 deletions(-) create mode 100644 util/gconv/gconv_float.go create mode 100644 util/gconv/gconv_int.go create mode 100644 util/gconv/gconv_uint.go diff --git a/util/gconv/gconv.go b/util/gconv/gconv.go index 60c4b3252..e7e1569fe 100644 --- a/util/gconv/gconv.go +++ b/util/gconv/gconv.go @@ -19,6 +19,7 @@ import ( "github.com/gogf/gf/v2/encoding/gbinary" "github.com/gogf/gf/v2/internal/json" + "github.com/gogf/gf/v2/internal/utils" "github.com/gogf/gf/v2/os/gtime" ) @@ -38,6 +39,18 @@ var ( StructTagPriority = []string{"gconv", "param", "params", "c", "p", "json"} ) +// Convert converts the variable `fromValue` to the type `toTypeName`, the type `toTypeName` is specified by string. +// The optional parameter `extraParams` is used for additional necessary parameter for this conversion. +// It supports common types conversion as its conversion based on type name string. +func Convert(fromValue interface{}, toTypeName string, extraParams ...interface{}) interface{} { + return doConvert(doConvertInput{ + FromValue: fromValue, + ToTypeName: toTypeName, + ReferValue: nil, + Extra: extraParams, + }) +} + type doConvertInput struct { FromValue interface{} // Value that is converted from. ToTypeName string // Target value type name in string. @@ -277,18 +290,6 @@ func doConvert(in doConvertInput) interface{} { } } -// Convert converts the variable `fromValue` to the type `toTypeName`, the type `toTypeName` is specified by string. -// The optional parameter `extraParams` is used for additional necessary parameter for this conversion. -// It supports common types conversion as its conversion based on type name string. -func Convert(fromValue interface{}, toTypeName string, extraParams ...interface{}) interface{} { - return doConvert(doConvertInput{ - FromValue: fromValue, - ToTypeName: toTypeName, - ReferValue: nil, - Extra: extraParams, - }) -} - // Byte converts `any` to byte. func Byte(any interface{}) byte { if v, ok := any.(byte); ok { @@ -311,22 +312,15 @@ func Bytes(any interface{}) []byte { if f, ok := value.(iBytes); ok { return f.Bytes() } - var ( - reflectValue = reflect.ValueOf(any) - reflectKind = reflectValue.Kind() - ) - for reflectKind == reflect.Ptr { - reflectValue = reflectValue.Elem() - reflectKind = reflectValue.Kind() - } - switch reflectKind { + originValueAndKind := utils.OriginValueAndKind(any) + switch originValueAndKind.OriginKind { case reflect.Array, reflect.Slice: var ( ok = true - bytes = make([]byte, reflectValue.Len()) + bytes = make([]byte, originValueAndKind.OriginValue.Len()) ) for i, _ := range bytes { - int32Value := Int32(reflectValue.Index(i).Interface()) + int32Value := Int32(originValueAndKind.OriginValue.Index(i).Interface()) if int32Value < 0 || int32Value > math.MaxUint8 { ok = false break @@ -505,280 +499,6 @@ func Bool(any interface{}) bool { } } -// Int converts `any` to int. -func Int(any interface{}) int { - if any == nil { - return 0 - } - if v, ok := any.(int); ok { - return v - } - return int(Int64(any)) -} - -// Int8 converts `any` to int8. -func Int8(any interface{}) int8 { - if any == nil { - return 0 - } - if v, ok := any.(int8); ok { - return v - } - return int8(Int64(any)) -} - -// Int16 converts `any` to int16. -func Int16(any interface{}) int16 { - if any == nil { - return 0 - } - if v, ok := any.(int16); ok { - return v - } - return int16(Int64(any)) -} - -// Int32 converts `any` to int32. -func Int32(any interface{}) int32 { - if any == nil { - return 0 - } - if v, ok := any.(int32); ok { - return v - } - return int32(Int64(any)) -} - -// Int64 converts `any` to int64. -func Int64(any interface{}) int64 { - if any == nil { - return 0 - } - switch value := any.(type) { - case int: - return int64(value) - case int8: - return int64(value) - case int16: - return int64(value) - case int32: - return int64(value) - case int64: - return value - case uint: - return int64(value) - case uint8: - return int64(value) - case uint16: - return int64(value) - case uint32: - return int64(value) - case uint64: - return int64(value) - case float32: - return int64(value) - case float64: - return int64(value) - case bool: - if value { - return 1 - } - return 0 - case []byte: - return gbinary.DecodeToInt64(value) - default: - if f, ok := value.(iInt64); ok { - return f.Int64() - } - s := String(value) - isMinus := false - if len(s) > 0 { - if s[0] == '-' { - isMinus = true - s = s[1:] - } else if s[0] == '+' { - s = s[1:] - } - } - // Hexadecimal - if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') { - if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil { - if isMinus { - return -v - } - return v - } - } - // Octal - if len(s) > 1 && s[0] == '0' { - if v, e := strconv.ParseInt(s[1:], 8, 64); e == nil { - if isMinus { - return -v - } - return v - } - } - // Decimal - if v, e := strconv.ParseInt(s, 10, 64); e == nil { - if isMinus { - return -v - } - return v - } - // Float64 - return int64(Float64(value)) - } -} - -// Uint converts `any` to uint. -func Uint(any interface{}) uint { - if any == nil { - return 0 - } - if v, ok := any.(uint); ok { - return v - } - return uint(Uint64(any)) -} - -// Uint8 converts `any` to uint8. -func Uint8(any interface{}) uint8 { - if any == nil { - return 0 - } - if v, ok := any.(uint8); ok { - return v - } - return uint8(Uint64(any)) -} - -// Uint16 converts `any` to uint16. -func Uint16(any interface{}) uint16 { - if any == nil { - return 0 - } - if v, ok := any.(uint16); ok { - return v - } - return uint16(Uint64(any)) -} - -// Uint32 converts `any` to uint32. -func Uint32(any interface{}) uint32 { - if any == nil { - return 0 - } - if v, ok := any.(uint32); ok { - return v - } - return uint32(Uint64(any)) -} - -// Uint64 converts `any` to uint64. -func Uint64(any interface{}) uint64 { - if any == nil { - return 0 - } - switch value := any.(type) { - case int: - return uint64(value) - case int8: - return uint64(value) - case int16: - return uint64(value) - case int32: - return uint64(value) - case int64: - return uint64(value) - case uint: - return uint64(value) - case uint8: - return uint64(value) - case uint16: - return uint64(value) - case uint32: - return uint64(value) - case uint64: - return value - case float32: - return uint64(value) - case float64: - return uint64(value) - case bool: - if value { - return 1 - } - return 0 - case []byte: - return gbinary.DecodeToUint64(value) - default: - if f, ok := value.(iUint64); ok { - return f.Uint64() - } - s := String(value) - // Hexadecimal - if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') { - if v, e := strconv.ParseUint(s[2:], 16, 64); e == nil { - return v - } - } - // Octal - if len(s) > 1 && s[0] == '0' { - if v, e := strconv.ParseUint(s[1:], 8, 64); e == nil { - return v - } - } - // Decimal - if v, e := strconv.ParseUint(s, 10, 64); e == nil { - return v - } - // Float64 - return uint64(Float64(value)) - } -} - -// Float32 converts `any` to float32. -func Float32(any interface{}) float32 { - if any == nil { - return 0 - } - switch value := any.(type) { - case float32: - return value - case float64: - return float32(value) - case []byte: - return gbinary.DecodeToFloat32(value) - default: - if f, ok := value.(iFloat32); ok { - return f.Float32() - } - v, _ := strconv.ParseFloat(String(any), 64) - return float32(v) - } -} - -// Float64 converts `any` to float64. -func Float64(any interface{}) float64 { - if any == nil { - return 0 - } - switch value := any.(type) { - case float32: - return float64(value) - case float64: - return value - case []byte: - return gbinary.DecodeToFloat64(value) - default: - if f, ok := value.(iFloat64); ok { - return f.Float64() - } - v, _ := strconv.ParseFloat(String(any), 64) - return v - } -} - // checkJsonAndUnmarshalUseNumber checks if given `any` is JSON formatted string value and does converting using `json.UnmarshalUseNumber`. func checkJsonAndUnmarshalUseNumber(any interface{}, target interface{}) bool { switch r := any.(type) { diff --git a/util/gconv/gconv_float.go b/util/gconv/gconv_float.go new file mode 100644 index 000000000..41cfb1cc7 --- /dev/null +++ b/util/gconv/gconv_float.go @@ -0,0 +1,55 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gconv + +import ( + "strconv" + + "github.com/gogf/gf/v2/encoding/gbinary" +) + +// Float32 converts `any` to float32. +func Float32(any interface{}) float32 { + if any == nil { + return 0 + } + switch value := any.(type) { + case float32: + return value + case float64: + return float32(value) + case []byte: + return gbinary.DecodeToFloat32(value) + default: + if f, ok := value.(iFloat32); ok { + return f.Float32() + } + v, _ := strconv.ParseFloat(String(any), 64) + return float32(v) + } +} + +// Float64 converts `any` to float64. +func Float64(any interface{}) float64 { + if any == nil { + return 0 + } + switch value := any.(type) { + case float32: + return float64(value) + case float64: + return value + case []byte: + return gbinary.DecodeToFloat64(value) + default: + if f, ok := value.(iFloat64); ok { + return f.Float64() + } + v, _ := strconv.ParseFloat(String(any), 64) + return v + } +} diff --git a/util/gconv/gconv_int.go b/util/gconv/gconv_int.go new file mode 100644 index 000000000..63bd77529 --- /dev/null +++ b/util/gconv/gconv_int.go @@ -0,0 +1,138 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gconv + +import ( + "strconv" + + "github.com/gogf/gf/v2/encoding/gbinary" +) + +// Int converts `any` to int. +func Int(any interface{}) int { + if any == nil { + return 0 + } + if v, ok := any.(int); ok { + return v + } + return int(Int64(any)) +} + +// Int8 converts `any` to int8. +func Int8(any interface{}) int8 { + if any == nil { + return 0 + } + if v, ok := any.(int8); ok { + return v + } + return int8(Int64(any)) +} + +// Int16 converts `any` to int16. +func Int16(any interface{}) int16 { + if any == nil { + return 0 + } + if v, ok := any.(int16); ok { + return v + } + return int16(Int64(any)) +} + +// Int32 converts `any` to int32. +func Int32(any interface{}) int32 { + if any == nil { + return 0 + } + if v, ok := any.(int32); ok { + return v + } + return int32(Int64(any)) +} + +// Int64 converts `any` to int64. +func Int64(any interface{}) int64 { + if any == nil { + return 0 + } + switch value := any.(type) { + case int: + return int64(value) + case int8: + return int64(value) + case int16: + return int64(value) + case int32: + return int64(value) + case int64: + return value + case uint: + return int64(value) + case uint8: + return int64(value) + case uint16: + return int64(value) + case uint32: + return int64(value) + case uint64: + return int64(value) + case float32: + return int64(value) + case float64: + return int64(value) + case bool: + if value { + return 1 + } + return 0 + case []byte: + return gbinary.DecodeToInt64(value) + default: + if f, ok := value.(iInt64); ok { + return f.Int64() + } + s := String(value) + isMinus := false + if len(s) > 0 { + if s[0] == '-' { + isMinus = true + s = s[1:] + } else if s[0] == '+' { + s = s[1:] + } + } + // Hexadecimal + if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') { + if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil { + if isMinus { + return -v + } + return v + } + } + // Octal + if len(s) > 1 && s[0] == '0' { + if v, e := strconv.ParseInt(s[1:], 8, 64); e == nil { + if isMinus { + return -v + } + return v + } + } + // Decimal + if v, e := strconv.ParseInt(s, 10, 64); e == nil { + if isMinus { + return -v + } + return v + } + // Float64 + return int64(Float64(value)) + } +} diff --git a/util/gconv/gconv_uint.go b/util/gconv/gconv_uint.go new file mode 100644 index 000000000..4f8d3b63a --- /dev/null +++ b/util/gconv/gconv_uint.go @@ -0,0 +1,120 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gconv + +import ( + "strconv" + + "github.com/gogf/gf/v2/encoding/gbinary" +) + +// Uint converts `any` to uint. +func Uint(any interface{}) uint { + if any == nil { + return 0 + } + if v, ok := any.(uint); ok { + return v + } + return uint(Uint64(any)) +} + +// Uint8 converts `any` to uint8. +func Uint8(any interface{}) uint8 { + if any == nil { + return 0 + } + if v, ok := any.(uint8); ok { + return v + } + return uint8(Uint64(any)) +} + +// Uint16 converts `any` to uint16. +func Uint16(any interface{}) uint16 { + if any == nil { + return 0 + } + if v, ok := any.(uint16); ok { + return v + } + return uint16(Uint64(any)) +} + +// Uint32 converts `any` to uint32. +func Uint32(any interface{}) uint32 { + if any == nil { + return 0 + } + if v, ok := any.(uint32); ok { + return v + } + return uint32(Uint64(any)) +} + +// Uint64 converts `any` to uint64. +func Uint64(any interface{}) uint64 { + if any == nil { + return 0 + } + switch value := any.(type) { + case int: + return uint64(value) + case int8: + return uint64(value) + case int16: + return uint64(value) + case int32: + return uint64(value) + case int64: + return uint64(value) + case uint: + return uint64(value) + case uint8: + return uint64(value) + case uint16: + return uint64(value) + case uint32: + return uint64(value) + case uint64: + return value + case float32: + return uint64(value) + case float64: + return uint64(value) + case bool: + if value { + return 1 + } + return 0 + case []byte: + return gbinary.DecodeToUint64(value) + default: + if f, ok := value.(iUint64); ok { + return f.Uint64() + } + s := String(value) + // Hexadecimal + if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') { + if v, e := strconv.ParseUint(s[2:], 16, 64); e == nil { + return v + } + } + // Octal + if len(s) > 1 && s[0] == '0' { + if v, e := strconv.ParseUint(s[1:], 8, 64); e == nil { + return v + } + } + // Decimal + if v, e := strconv.ParseUint(s, 10, 64); e == nil { + return v + } + // Float64 + return uint64(Float64(value)) + } +}