mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
up
This commit is contained in:
@ -39,7 +39,7 @@ var (
|
||||
// RegisterConverter registers custom converter.
|
||||
// Deprecated: use RegisterTypeConverterFunc instead for clear
|
||||
func RegisterConverter(fn any) (err error) {
|
||||
return defaultConverter.RegisterTypeConverterFunc(fn)
|
||||
return RegisterTypeConverterFunc(fn)
|
||||
}
|
||||
|
||||
// RegisterTypeConverterFunc registers custom converter.
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
// The optional parameter `extraParams` is used for additional necessary parameter for this conversion.
|
||||
// It supports common basic types conversion as its conversion based on type name string.
|
||||
func Convert(fromValue any, toTypeName string, extraParams ...any) any {
|
||||
return defaultConverter.doConvert(
|
||||
result, _ := defaultConverter.doConvert(
|
||||
doConvertInput{
|
||||
FromValue: fromValue,
|
||||
ToTypeName: toTypeName,
|
||||
@ -23,6 +23,7 @@ func Convert(fromValue any, toTypeName string, extraParams ...any) any {
|
||||
Extra: extraParams,
|
||||
},
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
// ConvertWithRefer converts the variable `fromValue` to the type referred by value `referValue`.
|
||||
@ -36,12 +37,11 @@ func ConvertWithRefer(fromValue any, referValue any, extraParams ...any) any {
|
||||
} else {
|
||||
referValueRf = reflect.ValueOf(referValue)
|
||||
}
|
||||
return defaultConverter.doConvert(
|
||||
doConvertInput{
|
||||
FromValue: fromValue,
|
||||
ToTypeName: referValueRf.Type().String(),
|
||||
ReferValue: referValue,
|
||||
Extra: extraParams,
|
||||
},
|
||||
)
|
||||
result, _ := defaultConverter.doConvert(doConvertInput{
|
||||
FromValue: fromValue,
|
||||
ToTypeName: referValueRf.Type().String(),
|
||||
ReferValue: referValue,
|
||||
Extra: extraParams,
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -7,14 +7,11 @@
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/structcache"
|
||||
)
|
||||
@ -26,9 +23,49 @@ type (
|
||||
)
|
||||
|
||||
// Converter is the manager for type converting.
|
||||
type Converter struct {
|
||||
internalConvertConfig *structcache.ConvertConfig
|
||||
typeConverterFuncMap map[converterInType]map[converterOutType]converterFunc
|
||||
type Converter interface {
|
||||
RegisterTypeConverterFunc(fn any) (err error)
|
||||
ConverterForInt
|
||||
ConverterForUint
|
||||
String(any any) (string, error)
|
||||
Bool(any any) (bool, error)
|
||||
Bytes(any any) ([]byte, error)
|
||||
Float32(any any) (float32, error)
|
||||
Float64(any any) (float64, error)
|
||||
|
||||
doMapConvert(
|
||||
value any, recursive recursiveType, mustMapReturn bool, option ...MapOption,
|
||||
) map[string]any
|
||||
MapToMap(params any, pointer any, mapping ...map[string]string) (err error)
|
||||
MapToMaps(params any, pointer any, paramKeyToAttrMap ...map[string]string) (err error)
|
||||
Rune(any any) (rune, error)
|
||||
Runes(any any) ([]rune, error)
|
||||
Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...map[string]string) (err error)
|
||||
Time(any interface{}, format ...string) (time.Time, error)
|
||||
Duration(any interface{}) (time.Duration, error)
|
||||
GTime(any interface{}, format ...string) (*gtime.Time, error)
|
||||
}
|
||||
|
||||
type ConverterForInt interface {
|
||||
Int(any any) (int, error)
|
||||
Int8(any any) (int8, error)
|
||||
Int16(any any) (int16, error)
|
||||
Int32(any any) (int32, error)
|
||||
Int64(any any) (int64, error)
|
||||
}
|
||||
|
||||
type ConverterForUint interface {
|
||||
Uint(any any) (uint, error)
|
||||
Uint8(any any) (uint8, error)
|
||||
Uin16(any any) (uint16, error)
|
||||
Uint32(any any) (uint32, error)
|
||||
Uint64(any any) (uint64, error)
|
||||
}
|
||||
|
||||
// impConverter implements the interface Converter.
|
||||
type impConverter struct {
|
||||
internalConverter *structcache.Converter
|
||||
typeConverterFuncMap map[converterInType]map[converterOutType]converterFunc
|
||||
}
|
||||
|
||||
var (
|
||||
@ -57,48 +94,15 @@ var (
|
||||
)
|
||||
|
||||
// NewConverter creates and returns management object for type converting.
|
||||
func NewConverter() *Converter {
|
||||
cf := &Converter{
|
||||
internalConvertConfig: structcache.NewConvertConfig(),
|
||||
typeConverterFuncMap: make(map[converterInType]map[converterOutType]converterFunc),
|
||||
func NewConverter() *impConverter {
|
||||
cf := &impConverter{
|
||||
internalConverter: structcache.NewConverter(),
|
||||
typeConverterFuncMap: make(map[converterInType]map[converterOutType]converterFunc),
|
||||
}
|
||||
cf.registerBuiltInConverter()
|
||||
return cf
|
||||
}
|
||||
|
||||
func (c *Converter) registerBuiltInConverter() {
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForInt64, intType, int8Type, int16Type, int32Type, int64Type,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForUint64, uintType, uint8Type, uint16Type, uint32Type, uint64Type,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForString, stringType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForFloat64, float32Type, float64Type,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForBool, boolType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForBytes, bytesType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForTime, timeType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForGTime, gtimeType,
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Converter) registerAnyConvertFuncForTypes(convertFunc AnyConvertFunc, types ...reflect.Type) {
|
||||
for _, t := range types {
|
||||
c.internalConvertConfig.RegisterAnyConvertFunc(t, convertFunc)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterTypeConverterFunc registers custom converter.
|
||||
// It must be registered before you use this custom converting feature.
|
||||
// It is suggested to do it in boot procedure of the process.
|
||||
@ -107,7 +111,7 @@ func (c *Converter) registerAnyConvertFuncForTypes(convertFunc AnyConvertFunc, t
|
||||
// 1. The parameter `fn` must be defined as pattern `func(T1) (T2, error)`.
|
||||
// It will convert type `T1` to type `T2`.
|
||||
// 2. The `T1` should not be type of pointer, but the `T2` should be type of pointer.
|
||||
func (c *Converter) RegisterTypeConverterFunc(fn any) (err error) {
|
||||
func (c *impConverter) RegisterTypeConverterFunc(fn any) (err error) {
|
||||
var (
|
||||
fnReflectType = reflect.TypeOf(fn)
|
||||
errType = reflect.TypeOf((*error)(nil)).Elem()
|
||||
@ -160,418 +164,39 @@ func (c *Converter) RegisterTypeConverterFunc(fn any) (err error) {
|
||||
return
|
||||
}
|
||||
registeredOutTypeMap[outType] = reflect.ValueOf(fn)
|
||||
c.internalConvertConfig.RegisterTypeConvertFunc(outType)
|
||||
c.internalConverter.RegisterTypeConvertFunc(outType)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Converter) getRegisteredConverterFuncAndSrcType(
|
||||
srcReflectValue, dstReflectValueForRefer reflect.Value,
|
||||
) (f converterFunc, srcType reflect.Type, ok bool) {
|
||||
if len(c.typeConverterFuncMap) == 0 {
|
||||
return reflect.Value{}, nil, false
|
||||
}
|
||||
srcType = srcReflectValue.Type()
|
||||
for srcType.Kind() == reflect.Pointer {
|
||||
srcType = srcType.Elem()
|
||||
}
|
||||
var registeredOutTypeMap map[converterOutType]converterFunc
|
||||
// firstly, it searches the map by input parameter type.
|
||||
registeredOutTypeMap, ok = c.typeConverterFuncMap[srcType]
|
||||
if !ok {
|
||||
return reflect.Value{}, nil, false
|
||||
}
|
||||
var dstType = dstReflectValueForRefer.Type()
|
||||
if dstType.Kind() == reflect.Pointer {
|
||||
// Might be **struct, which is support as designed.
|
||||
if dstType.Elem().Kind() == reflect.Pointer {
|
||||
dstType = dstType.Elem()
|
||||
}
|
||||
} else if dstReflectValueForRefer.IsValid() && dstReflectValueForRefer.CanAddr() {
|
||||
dstType = dstReflectValueForRefer.Addr().Type()
|
||||
} else {
|
||||
dstType = reflect.PointerTo(dstType)
|
||||
}
|
||||
// secondly, it searches the input parameter type map
|
||||
// and finds the result converter function by the output parameter type.
|
||||
f, ok = registeredOutTypeMap[dstType]
|
||||
if !ok {
|
||||
return reflect.Value{}, nil, false
|
||||
}
|
||||
return
|
||||
func (c *impConverter) registerBuiltInConverter() {
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForInt64, intType, int8Type, int16Type, int32Type, int64Type,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForUint64, uintType, uint8Type, uint16Type, uint32Type, uint64Type,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForString, stringType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForFloat64, float32Type, float64Type,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForBool, boolType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForBytes, bytesType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForTime, timeType,
|
||||
)
|
||||
c.registerAnyConvertFuncForTypes(
|
||||
c.builtInAnyConvertFuncForGTime, gtimeType,
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Converter) callCustomConverterWithRefer(
|
||||
srcReflectValue, referReflectValue reflect.Value,
|
||||
) (dstReflectValue reflect.Value, converted bool, err error) {
|
||||
registeredConverterFunc, srcType, ok := c.getRegisteredConverterFuncAndSrcType(srcReflectValue, referReflectValue)
|
||||
if !ok {
|
||||
return reflect.Value{}, false, nil
|
||||
}
|
||||
dstReflectValue = reflect.New(referReflectValue.Type()).Elem()
|
||||
converted, err = c.doCallCustomConverter(srcReflectValue, dstReflectValue, registeredConverterFunc, srcType)
|
||||
return
|
||||
}
|
||||
|
||||
// callCustomConverter call the custom converter. It will try some possible type.
|
||||
func (c *Converter) callCustomConverter(srcReflectValue, dstReflectValue reflect.Value) (converted bool, err error) {
|
||||
registeredConverterFunc, srcType, ok := c.getRegisteredConverterFuncAndSrcType(srcReflectValue, dstReflectValue)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
return c.doCallCustomConverter(srcReflectValue, dstReflectValue, registeredConverterFunc, srcType)
|
||||
}
|
||||
|
||||
func (c *Converter) doCallCustomConverter(
|
||||
srcReflectValue reflect.Value,
|
||||
dstReflectValue reflect.Value,
|
||||
registeredConverterFunc converterFunc,
|
||||
srcType reflect.Type,
|
||||
) (converted bool, err error) {
|
||||
// Converter function calling.
|
||||
for srcReflectValue.Type() != srcType {
|
||||
srcReflectValue = srcReflectValue.Elem()
|
||||
}
|
||||
result := registeredConverterFunc.Call([]reflect.Value{srcReflectValue})
|
||||
if !result[1].IsNil() {
|
||||
return false, result[1].Interface().(error)
|
||||
}
|
||||
// The `result[0]` is a pointer.
|
||||
if result[0].IsNil() {
|
||||
return false, nil
|
||||
}
|
||||
var resultValue = result[0]
|
||||
for {
|
||||
if resultValue.Type() == dstReflectValue.Type() && dstReflectValue.CanSet() {
|
||||
dstReflectValue.Set(resultValue)
|
||||
converted = true
|
||||
} else if dstReflectValue.Kind() == reflect.Pointer {
|
||||
if resultValue.Type() == dstReflectValue.Elem().Type() && dstReflectValue.Elem().CanSet() {
|
||||
dstReflectValue.Elem().Set(resultValue)
|
||||
converted = true
|
||||
}
|
||||
}
|
||||
if converted {
|
||||
break
|
||||
}
|
||||
if resultValue.Kind() == reflect.Pointer {
|
||||
resultValue = resultValue.Elem()
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return converted, nil
|
||||
}
|
||||
|
||||
type doConvertInput struct {
|
||||
FromValue interface{} // Value that is converted from.
|
||||
ToTypeName string // Target value type name in string.
|
||||
ReferValue interface{} // Referred value, a value in type `ToTypeName`. Note that its type might be reflect.Value.
|
||||
Extra []interface{} // Extra values for implementing the converting.
|
||||
|
||||
// Marks that the value is already converted and set to `ReferValue`. Caller can ignore the returned result.
|
||||
// It is an attribute for internal usage purpose.
|
||||
alreadySetToReferValue bool
|
||||
}
|
||||
|
||||
// doConvert does commonly use types converting.
|
||||
func (c *Converter) doConvert(in doConvertInput) (convertedValue interface{}) {
|
||||
switch in.ToTypeName {
|
||||
case "int":
|
||||
return Int(in.FromValue)
|
||||
case "*int":
|
||||
if _, ok := in.FromValue.(*int); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Int(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "int8":
|
||||
return Int8(in.FromValue)
|
||||
case "*int8":
|
||||
if _, ok := in.FromValue.(*int8); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Int8(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "int16":
|
||||
return Int16(in.FromValue)
|
||||
case "*int16":
|
||||
if _, ok := in.FromValue.(*int16); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Int16(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "int32":
|
||||
return Int32(in.FromValue)
|
||||
case "*int32":
|
||||
if _, ok := in.FromValue.(*int32); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Int32(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "int64":
|
||||
return Int64(in.FromValue)
|
||||
case "*int64":
|
||||
if _, ok := in.FromValue.(*int64); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Int64(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "uint":
|
||||
return Uint(in.FromValue)
|
||||
case "*uint":
|
||||
if _, ok := in.FromValue.(*uint); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Uint(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "uint8":
|
||||
return Uint8(in.FromValue)
|
||||
case "*uint8":
|
||||
if _, ok := in.FromValue.(*uint8); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Uint8(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "uint16":
|
||||
return Uint16(in.FromValue)
|
||||
case "*uint16":
|
||||
if _, ok := in.FromValue.(*uint16); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Uint16(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "uint32":
|
||||
return Uint32(in.FromValue)
|
||||
case "*uint32":
|
||||
if _, ok := in.FromValue.(*uint32); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Uint32(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "uint64":
|
||||
return Uint64(in.FromValue)
|
||||
case "*uint64":
|
||||
if _, ok := in.FromValue.(*uint64); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Uint64(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "float32":
|
||||
return Float32(in.FromValue)
|
||||
case "*float32":
|
||||
if _, ok := in.FromValue.(*float32); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Float32(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "float64":
|
||||
return Float64(in.FromValue)
|
||||
case "*float64":
|
||||
if _, ok := in.FromValue.(*float64); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Float64(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "bool":
|
||||
return Bool(in.FromValue)
|
||||
case "*bool":
|
||||
if _, ok := in.FromValue.(*bool); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Bool(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "string":
|
||||
return String(in.FromValue)
|
||||
case "*string":
|
||||
if _, ok := in.FromValue.(*string); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := String(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "[]byte":
|
||||
return Bytes(in.FromValue)
|
||||
case "[]int":
|
||||
return Ints(in.FromValue)
|
||||
case "[]int32":
|
||||
return Int32s(in.FromValue)
|
||||
case "[]int64":
|
||||
return Int64s(in.FromValue)
|
||||
case "[]uint":
|
||||
return Uints(in.FromValue)
|
||||
case "[]uint8":
|
||||
return Bytes(in.FromValue)
|
||||
case "[]uint32":
|
||||
return Uint32s(in.FromValue)
|
||||
case "[]uint64":
|
||||
return Uint64s(in.FromValue)
|
||||
case "[]float32":
|
||||
return Float32s(in.FromValue)
|
||||
case "[]float64":
|
||||
return Float64s(in.FromValue)
|
||||
case "[]string":
|
||||
return Strings(in.FromValue)
|
||||
|
||||
case "Time", "time.Time":
|
||||
if len(in.Extra) > 0 {
|
||||
return Time(in.FromValue, String(in.Extra[0]))
|
||||
}
|
||||
return Time(in.FromValue)
|
||||
case "*time.Time":
|
||||
var v time.Time
|
||||
if len(in.Extra) > 0 {
|
||||
v = Time(in.FromValue, String(in.Extra[0]))
|
||||
} else {
|
||||
if _, ok := in.FromValue.(*time.Time); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v = Time(in.FromValue)
|
||||
}
|
||||
return &v
|
||||
|
||||
case "GTime", "gtime.Time":
|
||||
if len(in.Extra) > 0 {
|
||||
if v := GTime(in.FromValue, String(in.Extra[0])); v != nil {
|
||||
return *v
|
||||
} else {
|
||||
return *gtime.New()
|
||||
}
|
||||
}
|
||||
if v := GTime(in.FromValue); v != nil {
|
||||
return *v
|
||||
} else {
|
||||
return *gtime.New()
|
||||
}
|
||||
case "*gtime.Time":
|
||||
if len(in.Extra) > 0 {
|
||||
if v := GTime(in.FromValue, String(in.Extra[0])); v != nil {
|
||||
return v
|
||||
} else {
|
||||
return gtime.New()
|
||||
}
|
||||
}
|
||||
if v := GTime(in.FromValue); v != nil {
|
||||
return v
|
||||
} else {
|
||||
return gtime.New()
|
||||
}
|
||||
|
||||
case "Duration", "time.Duration":
|
||||
return Duration(in.FromValue)
|
||||
case "*time.Duration":
|
||||
if _, ok := in.FromValue.(*time.Duration); ok {
|
||||
return in.FromValue
|
||||
}
|
||||
v := Duration(in.FromValue)
|
||||
return &v
|
||||
|
||||
case "map[string]string":
|
||||
return MapStrStr(in.FromValue)
|
||||
|
||||
case "map[string]interface {}":
|
||||
return Map(in.FromValue)
|
||||
|
||||
case "[]map[string]interface {}":
|
||||
return Maps(in.FromValue)
|
||||
|
||||
case "RawMessage", "json.RawMessage":
|
||||
// issue 3449
|
||||
bytes, err := json.Marshal(in.FromValue)
|
||||
if err != nil {
|
||||
intlog.Errorf(context.TODO(), `%+v`, err)
|
||||
}
|
||||
return bytes
|
||||
|
||||
default:
|
||||
if in.ReferValue != nil {
|
||||
var referReflectValue reflect.Value
|
||||
if v, ok := in.ReferValue.(reflect.Value); ok {
|
||||
referReflectValue = v
|
||||
} else {
|
||||
referReflectValue = reflect.ValueOf(in.ReferValue)
|
||||
}
|
||||
var fromReflectValue reflect.Value
|
||||
if v, ok := in.FromValue.(reflect.Value); ok {
|
||||
fromReflectValue = v
|
||||
} else {
|
||||
fromReflectValue = reflect.ValueOf(in.FromValue)
|
||||
}
|
||||
|
||||
// custom converter.
|
||||
if dstReflectValue, ok, _ := c.callCustomConverterWithRefer(fromReflectValue, referReflectValue); ok {
|
||||
return dstReflectValue.Interface()
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if recover() != nil {
|
||||
in.alreadySetToReferValue = false
|
||||
if err := c.bindVarToReflectValue(referReflectValue, in.FromValue, nil); err == nil {
|
||||
in.alreadySetToReferValue = true
|
||||
convertedValue = referReflectValue.Interface()
|
||||
}
|
||||
}
|
||||
}()
|
||||
switch referReflectValue.Kind() {
|
||||
case reflect.Ptr:
|
||||
// Type converting for custom type pointers.
|
||||
// Eg:
|
||||
// type PayMode int
|
||||
// type Req struct{
|
||||
// Mode *PayMode
|
||||
// }
|
||||
//
|
||||
// Struct(`{"Mode": 1000}`, &req)
|
||||
originType := referReflectValue.Type().Elem()
|
||||
switch originType.Kind() {
|
||||
case reflect.Struct:
|
||||
// Not support some kinds.
|
||||
default:
|
||||
in.ToTypeName = originType.Kind().String()
|
||||
in.ReferValue = nil
|
||||
refElementValue := reflect.ValueOf(c.doConvert(in))
|
||||
originTypeValue := reflect.New(refElementValue.Type()).Elem()
|
||||
originTypeValue.Set(refElementValue)
|
||||
in.alreadySetToReferValue = true
|
||||
return originTypeValue.Addr().Convert(referReflectValue.Type()).Interface()
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
var targetValue = reflect.New(referReflectValue.Type()).Elem()
|
||||
if err := c.MapToMap(in.FromValue, targetValue); err == nil {
|
||||
in.alreadySetToReferValue = true
|
||||
}
|
||||
return targetValue.Interface()
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
in.ToTypeName = referReflectValue.Kind().String()
|
||||
in.ReferValue = nil
|
||||
in.alreadySetToReferValue = true
|
||||
convertedValue = reflect.ValueOf(c.doConvert(in)).Convert(referReflectValue.Type()).Interface()
|
||||
return convertedValue
|
||||
}
|
||||
return in.FromValue
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Converter) doConvertWithReflectValueSet(reflectValue reflect.Value, in doConvertInput) {
|
||||
convertedValue := c.doConvert(in)
|
||||
if !in.alreadySetToReferValue {
|
||||
reflectValue.Set(reflect.ValueOf(convertedValue))
|
||||
func (c *impConverter) registerAnyConvertFuncForTypes(convertFunc AnyConvertFunc, types ...reflect.Type) {
|
||||
for _, t := range types {
|
||||
c.internalConverter.RegisterAnyConvertFunc(t, convertFunc)
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,8 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *Converter) Bool(any any) (bool, error) {
|
||||
// Bool converts `any` to bool.
|
||||
func (c *impConverter) Bool(any any) (bool, error) {
|
||||
if empty.IsNil(any) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForInt64(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForInt64(from any, to reflect.Value) error {
|
||||
v, err := c.Int64(from)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -22,7 +22,7 @@ func (c *Converter) builtInAnyConvertFuncForInt64(from any, to reflect.Value) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForUint64(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForUint64(from any, to reflect.Value) error {
|
||||
v, err := c.Uint64(from)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -31,7 +31,7 @@ func (c *Converter) builtInAnyConvertFuncForUint64(from any, to reflect.Value) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForString(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForString(from any, to reflect.Value) error {
|
||||
v, err := c.String(from)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -40,7 +40,7 @@ func (c *Converter) builtInAnyConvertFuncForString(from any, to reflect.Value) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForFloat64(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForFloat64(from any, to reflect.Value) error {
|
||||
v, err := c.Float64(from)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -49,7 +49,7 @@ func (c *Converter) builtInAnyConvertFuncForFloat64(from any, to reflect.Value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForBool(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForBool(from any, to reflect.Value) error {
|
||||
v, err := c.Bool(from)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -58,7 +58,7 @@ func (c *Converter) builtInAnyConvertFuncForBool(from any, to reflect.Value) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForBytes(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForBytes(from any, to reflect.Value) error {
|
||||
v, err := c.Bytes(from)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -67,7 +67,7 @@ func (c *Converter) builtInAnyConvertFuncForBytes(from any, to reflect.Value) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForTime(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForTime(from any, to reflect.Value) error {
|
||||
t, err := c.Time(from)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -76,7 +76,7 @@ func (c *Converter) builtInAnyConvertFuncForTime(from any, to reflect.Value) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) builtInAnyConvertFuncForGTime(from any, to reflect.Value) error {
|
||||
func (c *impConverter) builtInAnyConvertFuncForGTime(from any, to reflect.Value) error {
|
||||
v, err := c.GTime(from)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *Converter) Bytes(any any) ([]byte, error) {
|
||||
func (c *impConverter) Bytes(any any) ([]byte, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
522
util/gconv/gconv_converter_convert.go
Normal file
522
util/gconv/gconv_converter_convert.go
Normal file
@ -0,0 +1,522 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type doConvertInput struct {
|
||||
FromValue any // Value that is converted from.
|
||||
ToTypeName string // Target value type name in string.
|
||||
ReferValue any // Referred value, a value in type `ToTypeName`. Note that its type might be reflect.Value.
|
||||
Extra []any // Extra values for implementing the converting.
|
||||
|
||||
// Marks that the value is already converted and set to `ReferValue`. Caller can ignore the returned result.
|
||||
// It is an attribute for internal usage purpose.
|
||||
alreadySetToReferValue bool
|
||||
}
|
||||
|
||||
// doConvert does commonly use types converting.
|
||||
func (c *impConverter) doConvert(in doConvertInput) (convertedValue any, err error) {
|
||||
switch in.ToTypeName {
|
||||
case "int":
|
||||
return c.Int(in.FromValue)
|
||||
case "*int":
|
||||
if _, ok := in.FromValue.(*int); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Int(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "int8":
|
||||
return c.Int8(in.FromValue)
|
||||
case "*int8":
|
||||
if _, ok := in.FromValue.(*int8); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Int8(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "int16":
|
||||
return c.Int16(in.FromValue)
|
||||
case "*int16":
|
||||
if _, ok := in.FromValue.(*int16); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Int16(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "int32":
|
||||
return c.Int32(in.FromValue)
|
||||
case "*int32":
|
||||
if _, ok := in.FromValue.(*int32); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Int32(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "int64":
|
||||
return c.Int64(in.FromValue)
|
||||
case "*int64":
|
||||
if _, ok := in.FromValue.(*int64); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Int64(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "uint":
|
||||
return c.Uint(in.FromValue)
|
||||
case "*uint":
|
||||
if _, ok := in.FromValue.(*uint); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Uint(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "uint8":
|
||||
return c.Uint8(in.FromValue)
|
||||
case "*uint8":
|
||||
if _, ok := in.FromValue.(*uint8); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Uint8(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "uint16":
|
||||
return c.Uint16(in.FromValue)
|
||||
case "*uint16":
|
||||
if _, ok := in.FromValue.(*uint16); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Uint16(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "uint32":
|
||||
return c.Uint32(in.FromValue)
|
||||
case "*uint32":
|
||||
if _, ok := in.FromValue.(*uint32); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Uint32(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "uint64":
|
||||
return c.Uint64(in.FromValue)
|
||||
case "*uint64":
|
||||
if _, ok := in.FromValue.(*uint64); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Uint64(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "float32":
|
||||
return c.Float32(in.FromValue)
|
||||
case "*float32":
|
||||
if _, ok := in.FromValue.(*float32); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Float32(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "float64":
|
||||
return c.Float64(in.FromValue)
|
||||
case "*float64":
|
||||
if _, ok := in.FromValue.(*float64); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Float64(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "bool":
|
||||
return c.Bool(in.FromValue)
|
||||
case "*bool":
|
||||
if _, ok := in.FromValue.(*bool); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Bool(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "string":
|
||||
return c.String(in.FromValue)
|
||||
case "*string":
|
||||
if _, ok := in.FromValue.(*string); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.String(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "[]byte":
|
||||
return c.Bytes(in.FromValue)
|
||||
case "[]int":
|
||||
return c.SliceInt(in.FromValue, SliceOption{})
|
||||
case "[]int32":
|
||||
return c.SliceInt32(in.FromValue, SliceOption{})
|
||||
case "[]int64":
|
||||
return c.SliceInt64(in.FromValue, SliceOption{})
|
||||
case "[]uint":
|
||||
return c.SliceUint(in.FromValue, SliceOption{})
|
||||
case "[]uint8":
|
||||
return c.Bytes(in.FromValue)
|
||||
case "[]uint32":
|
||||
return c.SliceUint32(in.FromValue, SliceOption{})
|
||||
case "[]uint64":
|
||||
return c.SliceUint64(in.FromValue, SliceOption{})
|
||||
case "[]float32":
|
||||
return c.SliceFloat32(in.FromValue, SliceOption{})
|
||||
case "[]float64":
|
||||
return c.SliceFloat64(in.FromValue, SliceOption{})
|
||||
case "[]string":
|
||||
return c.SliceStr(in.FromValue, SliceOption{})
|
||||
|
||||
case "Time", "time.Time":
|
||||
if len(in.Extra) > 0 {
|
||||
s, err := c.String(in.Extra[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Time(in.FromValue, s)
|
||||
}
|
||||
return c.Time(in.FromValue)
|
||||
case "*time.Time":
|
||||
var v time.Time
|
||||
if len(in.Extra) > 0 {
|
||||
s, err := c.String(in.Extra[0])
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
v, err = c.Time(in.FromValue, s)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
} else {
|
||||
if _, ok := in.FromValue.(*time.Time); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err = c.Time(in.FromValue)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "GTime", "gtime.Time":
|
||||
if len(in.Extra) > 0 {
|
||||
s, err := c.String(in.Extra[0])
|
||||
if err != nil {
|
||||
return *gtime.New(), err
|
||||
}
|
||||
v, err := c.GTime(in.FromValue, s)
|
||||
if err != nil {
|
||||
return *gtime.New(), err
|
||||
}
|
||||
if v != nil {
|
||||
return *v, nil
|
||||
}
|
||||
return *gtime.New(), nil
|
||||
}
|
||||
v, err := c.GTime(in.FromValue)
|
||||
if err != nil {
|
||||
return *gtime.New(), err
|
||||
}
|
||||
if v != nil {
|
||||
return *v, nil
|
||||
}
|
||||
return *gtime.New(), nil
|
||||
case "*gtime.Time":
|
||||
if len(in.Extra) > 0 {
|
||||
s, err := c.String(in.Extra[0])
|
||||
if err != nil {
|
||||
return gtime.New(), err
|
||||
}
|
||||
v, err := c.GTime(in.FromValue, s)
|
||||
if err != nil {
|
||||
return gtime.New(), err
|
||||
}
|
||||
if v != nil {
|
||||
return v, nil
|
||||
}
|
||||
return gtime.New(), nil
|
||||
}
|
||||
v, err := c.GTime(in.FromValue)
|
||||
if err != nil {
|
||||
return gtime.New(), err
|
||||
}
|
||||
if v != nil {
|
||||
return v, nil
|
||||
}
|
||||
return gtime.New(), nil
|
||||
|
||||
case "Duration", "time.Duration":
|
||||
return c.Duration(in.FromValue)
|
||||
case "*time.Duration":
|
||||
if _, ok := in.FromValue.(*time.Duration); ok {
|
||||
return in.FromValue, nil
|
||||
}
|
||||
v, err := c.Duration(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v, nil
|
||||
|
||||
case "map[string]string":
|
||||
return MapStrStr(in.FromValue), nil
|
||||
|
||||
case "map[string]interface {}":
|
||||
return Map(in.FromValue, MapOption{}), nil
|
||||
|
||||
case "[]map[string]interface {}":
|
||||
return c.SliceMap(in.FromValue, SliceOption{}, MapOption{})
|
||||
|
||||
case "RawMessage", "json.RawMessage":
|
||||
// issue 3449
|
||||
bytes, err := json.Marshal(in.FromValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes, nil
|
||||
|
||||
default:
|
||||
if in.ReferValue != nil {
|
||||
var referReflectValue reflect.Value
|
||||
if v, ok := in.ReferValue.(reflect.Value); ok {
|
||||
referReflectValue = v
|
||||
} else {
|
||||
referReflectValue = reflect.ValueOf(in.ReferValue)
|
||||
}
|
||||
var fromReflectValue reflect.Value
|
||||
if v, ok := in.FromValue.(reflect.Value); ok {
|
||||
fromReflectValue = v
|
||||
} else {
|
||||
fromReflectValue = reflect.ValueOf(in.FromValue)
|
||||
}
|
||||
|
||||
// custom converter.
|
||||
dstReflectValue, ok, err := c.callCustomConverterWithRefer(fromReflectValue, referReflectValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok {
|
||||
return dstReflectValue.Interface(), nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if recover() != nil {
|
||||
in.alreadySetToReferValue = false
|
||||
if err := c.bindVarToReflectValue(referReflectValue, in.FromValue, nil); err == nil {
|
||||
in.alreadySetToReferValue = true
|
||||
convertedValue = referReflectValue.Interface()
|
||||
}
|
||||
}
|
||||
}()
|
||||
switch referReflectValue.Kind() {
|
||||
case reflect.Ptr:
|
||||
// Type converting for custom type pointers.
|
||||
// Eg:
|
||||
// type PayMode int
|
||||
// type Req struct{
|
||||
// Mode *PayMode
|
||||
// }
|
||||
//
|
||||
// Struct(`{"Mode": 1000}`, &req)
|
||||
originType := referReflectValue.Type().Elem()
|
||||
switch originType.Kind() {
|
||||
case reflect.Struct:
|
||||
// Not support some kinds.
|
||||
default:
|
||||
in.ToTypeName = originType.Kind().String()
|
||||
in.ReferValue = nil
|
||||
result, err := c.doConvert(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refElementValue := reflect.ValueOf(result)
|
||||
originTypeValue := reflect.New(refElementValue.Type()).Elem()
|
||||
originTypeValue.Set(refElementValue)
|
||||
in.alreadySetToReferValue = true
|
||||
return originTypeValue.Addr().Convert(referReflectValue.Type()).Interface(), nil
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
var targetValue = reflect.New(referReflectValue.Type()).Elem()
|
||||
if err = c.MapToMap(in.FromValue, targetValue); err == nil {
|
||||
in.alreadySetToReferValue = true
|
||||
}
|
||||
return targetValue.Interface(), nil
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
in.ToTypeName = referReflectValue.Kind().String()
|
||||
in.ReferValue = nil
|
||||
in.alreadySetToReferValue = true
|
||||
result, err := c.doConvert(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
convertedValue = reflect.ValueOf(result).Convert(referReflectValue.Type()).Interface()
|
||||
return convertedValue, nil
|
||||
}
|
||||
return in.FromValue, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *impConverter) doConvertWithReflectValueSet(reflectValue reflect.Value, in doConvertInput) error {
|
||||
convertedValue, err := c.doConvert(in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !in.alreadySetToReferValue {
|
||||
reflectValue.Set(reflect.ValueOf(convertedValue))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *impConverter) getRegisteredConverterFuncAndSrcType(
|
||||
srcReflectValue, dstReflectValueForRefer reflect.Value,
|
||||
) (f converterFunc, srcType reflect.Type, ok bool) {
|
||||
if len(c.typeConverterFuncMap) == 0 {
|
||||
return reflect.Value{}, nil, false
|
||||
}
|
||||
srcType = srcReflectValue.Type()
|
||||
for srcType.Kind() == reflect.Pointer {
|
||||
srcType = srcType.Elem()
|
||||
}
|
||||
var registeredOutTypeMap map[converterOutType]converterFunc
|
||||
// firstly, it searches the map by input parameter type.
|
||||
registeredOutTypeMap, ok = c.typeConverterFuncMap[srcType]
|
||||
if !ok {
|
||||
return reflect.Value{}, nil, false
|
||||
}
|
||||
var dstType = dstReflectValueForRefer.Type()
|
||||
if dstType.Kind() == reflect.Pointer {
|
||||
// Might be **struct, which is support as designed.
|
||||
if dstType.Elem().Kind() == reflect.Pointer {
|
||||
dstType = dstType.Elem()
|
||||
}
|
||||
} else if dstReflectValueForRefer.IsValid() && dstReflectValueForRefer.CanAddr() {
|
||||
dstType = dstReflectValueForRefer.Addr().Type()
|
||||
} else {
|
||||
dstType = reflect.PointerTo(dstType)
|
||||
}
|
||||
// secondly, it searches the input parameter type map
|
||||
// and finds the result converter function by the output parameter type.
|
||||
f, ok = registeredOutTypeMap[dstType]
|
||||
if !ok {
|
||||
return reflect.Value{}, nil, false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *impConverter) callCustomConverterWithRefer(
|
||||
srcReflectValue, referReflectValue reflect.Value,
|
||||
) (dstReflectValue reflect.Value, converted bool, err error) {
|
||||
registeredConverterFunc, srcType, ok := c.getRegisteredConverterFuncAndSrcType(srcReflectValue, referReflectValue)
|
||||
if !ok {
|
||||
return reflect.Value{}, false, nil
|
||||
}
|
||||
dstReflectValue = reflect.New(referReflectValue.Type()).Elem()
|
||||
converted, err = c.doCallCustomConverter(srcReflectValue, dstReflectValue, registeredConverterFunc, srcType)
|
||||
return
|
||||
}
|
||||
|
||||
// callCustomConverter call the custom converter. It will try some possible type.
|
||||
func (c *impConverter) callCustomConverter(srcReflectValue, dstReflectValue reflect.Value) (converted bool, err error) {
|
||||
registeredConverterFunc, srcType, ok := c.getRegisteredConverterFuncAndSrcType(srcReflectValue, dstReflectValue)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
return c.doCallCustomConverter(srcReflectValue, dstReflectValue, registeredConverterFunc, srcType)
|
||||
}
|
||||
|
||||
func (c *impConverter) doCallCustomConverter(
|
||||
srcReflectValue reflect.Value,
|
||||
dstReflectValue reflect.Value,
|
||||
registeredConverterFunc converterFunc,
|
||||
srcType reflect.Type,
|
||||
) (converted bool, err error) {
|
||||
// Converter function calling.
|
||||
for srcReflectValue.Type() != srcType {
|
||||
srcReflectValue = srcReflectValue.Elem()
|
||||
}
|
||||
result := registeredConverterFunc.Call([]reflect.Value{srcReflectValue})
|
||||
if !result[1].IsNil() {
|
||||
return false, result[1].Interface().(error)
|
||||
}
|
||||
// The `result[0]` is a pointer.
|
||||
if result[0].IsNil() {
|
||||
return false, nil
|
||||
}
|
||||
var resultValue = result[0]
|
||||
for {
|
||||
if resultValue.Type() == dstReflectValue.Type() && dstReflectValue.CanSet() {
|
||||
dstReflectValue.Set(resultValue)
|
||||
converted = true
|
||||
} else if dstReflectValue.Kind() == reflect.Pointer {
|
||||
if resultValue.Type() == dstReflectValue.Elem().Type() && dstReflectValue.Elem().CanSet() {
|
||||
dstReflectValue.Elem().Set(resultValue)
|
||||
converted = true
|
||||
}
|
||||
}
|
||||
if converted {
|
||||
break
|
||||
}
|
||||
if resultValue.Kind() == reflect.Pointer {
|
||||
resultValue = resultValue.Elem()
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return converted, nil
|
||||
}
|
||||
504
util/gconv/gconv_converter_doMapConvert.go
Normal file
504
util/gconv/gconv_converter_doMapConvert.go
Normal file
@ -0,0 +1,504 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
// MapConvert implements the map converting.
|
||||
// It automatically checks and converts json string to map if `value` is string/[]byte.
|
||||
//
|
||||
// TODO completely implement the recursive converting for all types, especially the map.
|
||||
func (c *impConverter) doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool, option ...MapOption) map[string]interface{} {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
// It redirects to its underlying value if it has implemented interface iVal.
|
||||
if v, ok := value.(localinterface.IVal); ok {
|
||||
value = v.Val()
|
||||
}
|
||||
var (
|
||||
usedOption = getUsedMapOption(option...)
|
||||
newTags = gtag.StructTagPriority
|
||||
)
|
||||
if usedOption.Deep {
|
||||
recursive = recursiveTypeTrue
|
||||
}
|
||||
switch len(usedOption.Tags) {
|
||||
case 0:
|
||||
// No need handling.
|
||||
case 1:
|
||||
newTags = append(strings.Split(usedOption.Tags[0], ","), gtag.StructTagPriority...)
|
||||
default:
|
||||
newTags = append(usedOption.Tags, gtag.StructTagPriority...)
|
||||
}
|
||||
// Assert the common combination of types, and finally it uses reflection.
|
||||
dataMap := make(map[string]interface{})
|
||||
switch r := value.(type) {
|
||||
case string:
|
||||
// If it is a JSON string, automatically unmarshal it!
|
||||
if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
|
||||
if err := json.UnmarshalUseNumber([]byte(r), &dataMap); err != nil {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case []byte:
|
||||
// If it is a JSON string, automatically unmarshal it!
|
||||
if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
|
||||
if err := json.UnmarshalUseNumber(r, &dataMap); err != nil {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case map[interface{}]interface{}:
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
}
|
||||
case map[interface{}]string:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]int:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]uint:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]float32:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]float64:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[string]bool:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]int:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]uint:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]float32:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]float64:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]string:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]interface{}:
|
||||
if recursive == recursiveTypeTrue {
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
// A copy of current map.
|
||||
for k, v := range r {
|
||||
dataMap[k] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// It returns the map directly without any changing.
|
||||
return r
|
||||
}
|
||||
case map[int]interface{}:
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
}
|
||||
case map[int]string:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[uint]string:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
|
||||
default:
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
var reflectValue reflect.Value
|
||||
if v, ok := value.(reflect.Value); ok {
|
||||
reflectValue = v
|
||||
} else {
|
||||
reflectValue = reflect.ValueOf(value)
|
||||
}
|
||||
reflectKind := reflectValue.Kind()
|
||||
// If it is a pointer, we should find its real data type.
|
||||
for reflectKind == reflect.Ptr {
|
||||
reflectValue = reflectValue.Elem()
|
||||
reflectKind = reflectValue.Kind()
|
||||
}
|
||||
switch reflectKind {
|
||||
// If `value` is type of array, it converts the value of even number index as its key and
|
||||
// the value of odd number index as its corresponding value, for example:
|
||||
// []string{"k1","v1","k2","v2"} => map[string]interface{}{"k1":"v1", "k2":"v2"}
|
||||
// []string{"k1","v1","k2"} => map[string]interface{}{"k1":"v1", "k2":nil}
|
||||
case reflect.Slice, reflect.Array:
|
||||
length := reflectValue.Len()
|
||||
for i := 0; i < length; i += 2 {
|
||||
if i+1 < length {
|
||||
dataMap[String(reflectValue.Index(i).Interface())] = reflectValue.Index(i + 1).Interface()
|
||||
} else {
|
||||
dataMap[String(reflectValue.Index(i).Interface())] = nil
|
||||
}
|
||||
}
|
||||
case reflect.Map, reflect.Struct, reflect.Interface:
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
convertedValue := c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: true,
|
||||
Value: value,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
MustMapReturn: mustMapReturn,
|
||||
},
|
||||
)
|
||||
if m, ok := convertedValue.(map[string]interface{}); ok {
|
||||
return m
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return dataMap
|
||||
}
|
||||
|
||||
func getUsedMapOption(option ...MapOption) MapOption {
|
||||
var usedOption MapOption
|
||||
if len(option) > 0 {
|
||||
usedOption = option[0]
|
||||
}
|
||||
return usedOption
|
||||
}
|
||||
|
||||
type doMapConvertForMapOrStructValueInput struct {
|
||||
IsRoot bool // It returns directly if it is not root and with no recursive converting.
|
||||
Value interface{} // Current operation value.
|
||||
RecursiveType recursiveType // The type from top function entry.
|
||||
RecursiveOption bool // Whether convert recursively for `current` operation.
|
||||
Option MapOption // Map converting option.
|
||||
MustMapReturn bool // Must return map instead of Value when empty.
|
||||
}
|
||||
|
||||
func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) interface{} {
|
||||
if !in.IsRoot && !in.RecursiveOption {
|
||||
return in.Value
|
||||
}
|
||||
|
||||
var reflectValue reflect.Value
|
||||
if v, ok := in.Value.(reflect.Value); ok {
|
||||
reflectValue = v
|
||||
in.Value = v.Interface()
|
||||
} else {
|
||||
reflectValue = reflect.ValueOf(in.Value)
|
||||
}
|
||||
reflectKind := reflectValue.Kind()
|
||||
// If it is a pointer, we should find its real data type.
|
||||
for reflectKind == reflect.Ptr {
|
||||
reflectValue = reflectValue.Elem()
|
||||
reflectKind = reflectValue.Kind()
|
||||
}
|
||||
switch reflectKind {
|
||||
case reflect.Map:
|
||||
var (
|
||||
mapIter = reflectValue.MapRange()
|
||||
dataMap = make(map[string]interface{})
|
||||
)
|
||||
for mapIter.Next() {
|
||||
var (
|
||||
mapKeyValue = mapIter.Value()
|
||||
mapValue interface{}
|
||||
)
|
||||
switch {
|
||||
case mapKeyValue.IsZero():
|
||||
if utils.CanCallIsNil(mapKeyValue) && mapKeyValue.IsNil() {
|
||||
// quick check for nil value.
|
||||
mapValue = nil
|
||||
} else {
|
||||
// in case of:
|
||||
// exception recovered: reflect: call of reflect.Value.Interface on zero Value
|
||||
mapValue = reflect.New(mapKeyValue.Type()).Elem().Interface()
|
||||
}
|
||||
default:
|
||||
mapValue = mapKeyValue.Interface()
|
||||
}
|
||||
dataMap[String(mapIter.Key().Interface())] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: mapValue,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
}
|
||||
return dataMap
|
||||
|
||||
case reflect.Struct:
|
||||
var dataMap = make(map[string]interface{})
|
||||
// Map converting interface check.
|
||||
if v, ok := in.Value.(localinterface.IMapStrAny); ok {
|
||||
// Value copy, in case of concurrent safety.
|
||||
for mapK, mapV := range v.MapStrAny() {
|
||||
if in.RecursiveOption {
|
||||
dataMap[mapK] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: mapV,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
dataMap[mapK] = mapV
|
||||
}
|
||||
}
|
||||
if len(dataMap) > 0 {
|
||||
return dataMap
|
||||
}
|
||||
}
|
||||
// Using reflect for converting.
|
||||
var (
|
||||
rtField reflect.StructField
|
||||
rvField reflect.Value
|
||||
reflectType = reflectValue.Type() // attribute value type.
|
||||
mapKey = "" // mapKey may be the tag name or the struct attribute name.
|
||||
)
|
||||
for i := 0; i < reflectValue.NumField(); i++ {
|
||||
rtField = reflectType.Field(i)
|
||||
rvField = reflectValue.Field(i)
|
||||
// Only convert the public attributes.
|
||||
fieldName := rtField.Name
|
||||
if !utils.IsLetterUpper(fieldName[0]) {
|
||||
continue
|
||||
}
|
||||
mapKey = ""
|
||||
fieldTag := rtField.Tag
|
||||
for _, tag := range in.Option.Tags {
|
||||
if mapKey = fieldTag.Get(tag); mapKey != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
if mapKey == "" {
|
||||
mapKey = fieldName
|
||||
} else {
|
||||
// Support json tag feature: -, omitempty
|
||||
mapKey = strings.TrimSpace(mapKey)
|
||||
if mapKey == "-" {
|
||||
continue
|
||||
}
|
||||
array := strings.Split(mapKey, ",")
|
||||
if len(array) > 1 {
|
||||
switch strings.TrimSpace(array[1]) {
|
||||
case "omitempty":
|
||||
if in.Option.OmitEmpty && empty.IsEmpty(rvField.Interface()) {
|
||||
continue
|
||||
} else {
|
||||
mapKey = strings.TrimSpace(array[0])
|
||||
}
|
||||
default:
|
||||
mapKey = strings.TrimSpace(array[0])
|
||||
}
|
||||
}
|
||||
if mapKey == "" {
|
||||
mapKey = fieldName
|
||||
}
|
||||
}
|
||||
if in.RecursiveOption || rtField.Anonymous {
|
||||
// Do map converting recursively.
|
||||
var (
|
||||
rvAttrField = rvField
|
||||
rvAttrKind = rvField.Kind()
|
||||
)
|
||||
if rvAttrKind == reflect.Ptr {
|
||||
rvAttrField = rvField.Elem()
|
||||
rvAttrKind = rvAttrField.Kind()
|
||||
}
|
||||
switch rvAttrKind {
|
||||
case reflect.Struct:
|
||||
// Embedded struct and has no fields, just ignores it.
|
||||
// Eg: gmeta.Meta
|
||||
if rvAttrField.Type().NumField() == 0 {
|
||||
continue
|
||||
}
|
||||
var (
|
||||
hasNoTag = mapKey == fieldName
|
||||
// DO NOT use rvAttrField.Interface() here,
|
||||
// as it might be changed from pointer to struct.
|
||||
rvInterface = rvField.Interface()
|
||||
)
|
||||
switch {
|
||||
case hasNoTag && rtField.Anonymous:
|
||||
// It means this attribute field has no tag.
|
||||
// Overwrite the attribute with sub-struct attribute fields.
|
||||
anonymousValue := c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvInterface,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: true,
|
||||
Option: in.Option,
|
||||
})
|
||||
if m, ok := anonymousValue.(map[string]interface{}); ok {
|
||||
for k, v := range m {
|
||||
dataMap[k] = v
|
||||
}
|
||||
} else {
|
||||
dataMap[mapKey] = rvInterface
|
||||
}
|
||||
|
||||
// It means this attribute field has desired tag.
|
||||
case !hasNoTag && rtField.Anonymous:
|
||||
dataMap[mapKey] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvInterface,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: true,
|
||||
Option: in.Option,
|
||||
})
|
||||
|
||||
default:
|
||||
dataMap[mapKey] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvInterface,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
})
|
||||
}
|
||||
|
||||
// The struct attribute is type of slice.
|
||||
case reflect.Array, reflect.Slice:
|
||||
length := rvAttrField.Len()
|
||||
if length == 0 {
|
||||
dataMap[mapKey] = rvAttrField.Interface()
|
||||
break
|
||||
}
|
||||
array := make([]interface{}, length)
|
||||
for arrayIndex := 0; arrayIndex < length; arrayIndex++ {
|
||||
array[arrayIndex] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvAttrField.Index(arrayIndex).Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
}
|
||||
dataMap[mapKey] = array
|
||||
case reflect.Map:
|
||||
var (
|
||||
mapIter = rvAttrField.MapRange()
|
||||
nestedMap = make(map[string]interface{})
|
||||
)
|
||||
for mapIter.Next() {
|
||||
nestedMap[String(mapIter.Key().Interface())] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: mapIter.Value().Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
}
|
||||
dataMap[mapKey] = nestedMap
|
||||
default:
|
||||
if rvField.IsValid() {
|
||||
dataMap[mapKey] = reflectValue.Field(i).Interface()
|
||||
} else {
|
||||
dataMap[mapKey] = nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No recursive map value converting
|
||||
if rvField.IsValid() {
|
||||
dataMap[mapKey] = reflectValue.Field(i).Interface()
|
||||
} else {
|
||||
dataMap[mapKey] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if !in.MustMapReturn && len(dataMap) == 0 {
|
||||
return in.Value
|
||||
}
|
||||
return dataMap
|
||||
|
||||
// The given value is type of slice.
|
||||
case reflect.Array, reflect.Slice:
|
||||
length := reflectValue.Len()
|
||||
if length == 0 {
|
||||
break
|
||||
}
|
||||
array := make([]interface{}, reflectValue.Len())
|
||||
for i := 0; i < length; i++ {
|
||||
array[i] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: reflectValue.Index(i).Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
})
|
||||
}
|
||||
return array
|
||||
|
||||
default:
|
||||
}
|
||||
return in.Value
|
||||
}
|
||||
@ -17,7 +17,7 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *Converter) Float32(any any) (float32, error) {
|
||||
func (c *impConverter) Float32(any any) (float32, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
@ -78,7 +78,7 @@ func (c *Converter) Float32(any any) (float32, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Converter) Float64(any any) (float64, error) {
|
||||
func (c *impConverter) Float64(any any) (float64, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *Converter) Int(any any) (int, error) {
|
||||
func (c *impConverter) Int(any any) (int, error) {
|
||||
if v, ok := any.(int); ok {
|
||||
return v, nil
|
||||
}
|
||||
@ -29,7 +29,7 @@ func (c *Converter) Int(any any) (int, error) {
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func (c *Converter) Int8(any any) (int8, error) {
|
||||
func (c *impConverter) Int8(any any) (int8, error) {
|
||||
if v, ok := any.(int8); ok {
|
||||
return v, nil
|
||||
}
|
||||
@ -40,7 +40,7 @@ func (c *Converter) Int8(any any) (int8, error) {
|
||||
return int8(v), nil
|
||||
}
|
||||
|
||||
func (c *Converter) Int16(any any) (int16, error) {
|
||||
func (c *impConverter) Int16(any any) (int16, error) {
|
||||
if v, ok := any.(int16); ok {
|
||||
return v, nil
|
||||
}
|
||||
@ -51,7 +51,7 @@ func (c *Converter) Int16(any any) (int16, error) {
|
||||
return int16(v), nil
|
||||
}
|
||||
|
||||
func (c *Converter) Int32(any any) (int32, error) {
|
||||
func (c *impConverter) Int32(any any) (int32, error) {
|
||||
if v, ok := any.(int32); ok {
|
||||
return v, nil
|
||||
}
|
||||
@ -62,7 +62,7 @@ func (c *Converter) Int32(any any) (int32, error) {
|
||||
return int32(v), nil
|
||||
}
|
||||
|
||||
func (c *Converter) Int64(any any) (int64, error) {
|
||||
func (c *impConverter) Int64(any any) (int64, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@ -6,499 +6,492 @@
|
||||
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
// MapConvert implements the map converting.
|
||||
// It automatically checks and converts json string to map if `value` is string/[]byte.
|
||||
//// MapStrStr converts `value` to map[string]string.
|
||||
//// Note that there might be data copy for this map type converting.
|
||||
//func (c *impConverter) MapStrStr(value any, option ...MapOption) (map[string]string, error) {
|
||||
// if r, ok := value.(map[string]string); ok {
|
||||
// return r, nil
|
||||
// }
|
||||
// m := Map(value, option...)
|
||||
// if len(m) > 0 {
|
||||
// vMap := make(map[string]string, len(m))
|
||||
// for k, v := range m {
|
||||
// s, err := c.String(v)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// vMap[k] = s
|
||||
// }
|
||||
// return vMap, nil
|
||||
// }
|
||||
// return nil, nil
|
||||
//}
|
||||
//
|
||||
// TODO completely implement the recursive converting for all types, especially the map.
|
||||
func (c *Converter) doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool, option ...MapOption) map[string]interface{} {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
// It redirects to its underlying value if it has implemented interface iVal.
|
||||
if v, ok := value.(localinterface.IVal); ok {
|
||||
value = v.Val()
|
||||
}
|
||||
var (
|
||||
usedOption = getUsedMapOption(option...)
|
||||
newTags = gtag.StructTagPriority
|
||||
)
|
||||
if usedOption.Deep {
|
||||
recursive = recursiveTypeTrue
|
||||
}
|
||||
switch len(usedOption.Tags) {
|
||||
case 0:
|
||||
// No need handling.
|
||||
case 1:
|
||||
newTags = append(strings.Split(usedOption.Tags[0], ","), gtag.StructTagPriority...)
|
||||
default:
|
||||
newTags = append(usedOption.Tags, gtag.StructTagPriority...)
|
||||
}
|
||||
// Assert the common combination of types, and finally it uses reflection.
|
||||
dataMap := make(map[string]interface{})
|
||||
switch r := value.(type) {
|
||||
case string:
|
||||
// If it is a JSON string, automatically unmarshal it!
|
||||
if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
|
||||
if err := json.UnmarshalUseNumber([]byte(r), &dataMap); err != nil {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case []byte:
|
||||
// If it is a JSON string, automatically unmarshal it!
|
||||
if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
|
||||
if err := json.UnmarshalUseNumber(r, &dataMap); err != nil {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case map[interface{}]interface{}:
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
}
|
||||
case map[interface{}]string:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]int:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]uint:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]float32:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[interface{}]float64:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[string]bool:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]int:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]uint:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]float32:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]float64:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]string:
|
||||
for k, v := range r {
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]interface{}:
|
||||
if recursive == recursiveTypeTrue {
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
// A copy of current map.
|
||||
for k, v := range r {
|
||||
dataMap[k] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// It returns the map directly without any changing.
|
||||
return r
|
||||
}
|
||||
case map[int]interface{}:
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
}
|
||||
case map[int]string:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
case map[uint]string:
|
||||
for k, v := range r {
|
||||
dataMap[String(k)] = v
|
||||
}
|
||||
|
||||
default:
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
var reflectValue reflect.Value
|
||||
if v, ok := value.(reflect.Value); ok {
|
||||
reflectValue = v
|
||||
} else {
|
||||
reflectValue = reflect.ValueOf(value)
|
||||
}
|
||||
reflectKind := reflectValue.Kind()
|
||||
// If it is a pointer, we should find its real data type.
|
||||
for reflectKind == reflect.Ptr {
|
||||
reflectValue = reflectValue.Elem()
|
||||
reflectKind = reflectValue.Kind()
|
||||
}
|
||||
switch reflectKind {
|
||||
// If `value` is type of array, it converts the value of even number index as its key and
|
||||
// the value of odd number index as its corresponding value, for example:
|
||||
// []string{"k1","v1","k2","v2"} => map[string]interface{}{"k1":"v1", "k2":"v2"}
|
||||
// []string{"k1","v1","k2"} => map[string]interface{}{"k1":"v1", "k2":nil}
|
||||
case reflect.Slice, reflect.Array:
|
||||
length := reflectValue.Len()
|
||||
for i := 0; i < length; i += 2 {
|
||||
if i+1 < length {
|
||||
dataMap[String(reflectValue.Index(i).Interface())] = reflectValue.Index(i + 1).Interface()
|
||||
} else {
|
||||
dataMap[String(reflectValue.Index(i).Interface())] = nil
|
||||
}
|
||||
}
|
||||
case reflect.Map, reflect.Struct, reflect.Interface:
|
||||
recursiveOption := usedOption
|
||||
recursiveOption.Tags = newTags
|
||||
convertedValue := c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: true,
|
||||
Value: value,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
MustMapReturn: mustMapReturn,
|
||||
},
|
||||
)
|
||||
if m, ok := convertedValue.(map[string]interface{}); ok {
|
||||
return m
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return dataMap
|
||||
}
|
||||
|
||||
func getUsedMapOption(option ...MapOption) MapOption {
|
||||
var usedOption MapOption
|
||||
if len(option) > 0 {
|
||||
usedOption = option[0]
|
||||
}
|
||||
return usedOption
|
||||
}
|
||||
|
||||
type doMapConvertForMapOrStructValueInput struct {
|
||||
IsRoot bool // It returns directly if it is not root and with no recursive converting.
|
||||
Value interface{} // Current operation value.
|
||||
RecursiveType recursiveType // The type from top function entry.
|
||||
RecursiveOption bool // Whether convert recursively for `current` operation.
|
||||
Option MapOption // Map converting option.
|
||||
MustMapReturn bool // Must return map instead of Value when empty.
|
||||
}
|
||||
|
||||
func (c *Converter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) interface{} {
|
||||
if !in.IsRoot && !in.RecursiveOption {
|
||||
return in.Value
|
||||
}
|
||||
|
||||
var reflectValue reflect.Value
|
||||
if v, ok := in.Value.(reflect.Value); ok {
|
||||
reflectValue = v
|
||||
in.Value = v.Interface()
|
||||
} else {
|
||||
reflectValue = reflect.ValueOf(in.Value)
|
||||
}
|
||||
reflectKind := reflectValue.Kind()
|
||||
// If it is a pointer, we should find its real data type.
|
||||
for reflectKind == reflect.Ptr {
|
||||
reflectValue = reflectValue.Elem()
|
||||
reflectKind = reflectValue.Kind()
|
||||
}
|
||||
switch reflectKind {
|
||||
case reflect.Map:
|
||||
var (
|
||||
mapIter = reflectValue.MapRange()
|
||||
dataMap = make(map[string]interface{})
|
||||
)
|
||||
for mapIter.Next() {
|
||||
var (
|
||||
mapKeyValue = mapIter.Value()
|
||||
mapValue interface{}
|
||||
)
|
||||
switch {
|
||||
case mapKeyValue.IsZero():
|
||||
if utils.CanCallIsNil(mapKeyValue) && mapKeyValue.IsNil() {
|
||||
// quick check for nil value.
|
||||
mapValue = nil
|
||||
} else {
|
||||
// in case of:
|
||||
// exception recovered: reflect: call of reflect.Value.Interface on zero Value
|
||||
mapValue = reflect.New(mapKeyValue.Type()).Elem().Interface()
|
||||
}
|
||||
default:
|
||||
mapValue = mapKeyValue.Interface()
|
||||
}
|
||||
dataMap[String(mapIter.Key().Interface())] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: mapValue,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
}
|
||||
return dataMap
|
||||
|
||||
case reflect.Struct:
|
||||
var dataMap = make(map[string]interface{})
|
||||
// Map converting interface check.
|
||||
if v, ok := in.Value.(localinterface.IMapStrAny); ok {
|
||||
// Value copy, in case of concurrent safety.
|
||||
for mapK, mapV := range v.MapStrAny() {
|
||||
if in.RecursiveOption {
|
||||
dataMap[mapK] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: mapV,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
dataMap[mapK] = mapV
|
||||
}
|
||||
}
|
||||
if len(dataMap) > 0 {
|
||||
return dataMap
|
||||
}
|
||||
}
|
||||
// Using reflect for converting.
|
||||
var (
|
||||
rtField reflect.StructField
|
||||
rvField reflect.Value
|
||||
reflectType = reflectValue.Type() // attribute value type.
|
||||
mapKey = "" // mapKey may be the tag name or the struct attribute name.
|
||||
)
|
||||
for i := 0; i < reflectValue.NumField(); i++ {
|
||||
rtField = reflectType.Field(i)
|
||||
rvField = reflectValue.Field(i)
|
||||
// Only convert the public attributes.
|
||||
fieldName := rtField.Name
|
||||
if !utils.IsLetterUpper(fieldName[0]) {
|
||||
continue
|
||||
}
|
||||
mapKey = ""
|
||||
fieldTag := rtField.Tag
|
||||
for _, tag := range in.Option.Tags {
|
||||
if mapKey = fieldTag.Get(tag); mapKey != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
if mapKey == "" {
|
||||
mapKey = fieldName
|
||||
} else {
|
||||
// Support json tag feature: -, omitempty
|
||||
mapKey = strings.TrimSpace(mapKey)
|
||||
if mapKey == "-" {
|
||||
continue
|
||||
}
|
||||
array := strings.Split(mapKey, ",")
|
||||
if len(array) > 1 {
|
||||
switch strings.TrimSpace(array[1]) {
|
||||
case "omitempty":
|
||||
if in.Option.OmitEmpty && empty.IsEmpty(rvField.Interface()) {
|
||||
continue
|
||||
} else {
|
||||
mapKey = strings.TrimSpace(array[0])
|
||||
}
|
||||
default:
|
||||
mapKey = strings.TrimSpace(array[0])
|
||||
}
|
||||
}
|
||||
if mapKey == "" {
|
||||
mapKey = fieldName
|
||||
}
|
||||
}
|
||||
if in.RecursiveOption || rtField.Anonymous {
|
||||
// Do map converting recursively.
|
||||
var (
|
||||
rvAttrField = rvField
|
||||
rvAttrKind = rvField.Kind()
|
||||
)
|
||||
if rvAttrKind == reflect.Ptr {
|
||||
rvAttrField = rvField.Elem()
|
||||
rvAttrKind = rvAttrField.Kind()
|
||||
}
|
||||
switch rvAttrKind {
|
||||
case reflect.Struct:
|
||||
// Embedded struct and has no fields, just ignores it.
|
||||
// Eg: gmeta.Meta
|
||||
if rvAttrField.Type().NumField() == 0 {
|
||||
continue
|
||||
}
|
||||
var (
|
||||
hasNoTag = mapKey == fieldName
|
||||
// DO NOT use rvAttrField.Interface() here,
|
||||
// as it might be changed from pointer to struct.
|
||||
rvInterface = rvField.Interface()
|
||||
)
|
||||
switch {
|
||||
case hasNoTag && rtField.Anonymous:
|
||||
// It means this attribute field has no tag.
|
||||
// Overwrite the attribute with sub-struct attribute fields.
|
||||
anonymousValue := c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvInterface,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: true,
|
||||
Option: in.Option,
|
||||
})
|
||||
if m, ok := anonymousValue.(map[string]interface{}); ok {
|
||||
for k, v := range m {
|
||||
dataMap[k] = v
|
||||
}
|
||||
} else {
|
||||
dataMap[mapKey] = rvInterface
|
||||
}
|
||||
|
||||
// It means this attribute field has desired tag.
|
||||
case !hasNoTag && rtField.Anonymous:
|
||||
dataMap[mapKey] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvInterface,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: true,
|
||||
Option: in.Option,
|
||||
})
|
||||
|
||||
default:
|
||||
dataMap[mapKey] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvInterface,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
})
|
||||
}
|
||||
|
||||
// The struct attribute is type of slice.
|
||||
case reflect.Array, reflect.Slice:
|
||||
length := rvAttrField.Len()
|
||||
if length == 0 {
|
||||
dataMap[mapKey] = rvAttrField.Interface()
|
||||
break
|
||||
}
|
||||
array := make([]interface{}, length)
|
||||
for arrayIndex := 0; arrayIndex < length; arrayIndex++ {
|
||||
array[arrayIndex] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: rvAttrField.Index(arrayIndex).Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
}
|
||||
dataMap[mapKey] = array
|
||||
case reflect.Map:
|
||||
var (
|
||||
mapIter = rvAttrField.MapRange()
|
||||
nestedMap = make(map[string]interface{})
|
||||
)
|
||||
for mapIter.Next() {
|
||||
nestedMap[String(mapIter.Key().Interface())] = c.doMapConvertForMapOrStructValue(
|
||||
doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: mapIter.Value().Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
}
|
||||
dataMap[mapKey] = nestedMap
|
||||
default:
|
||||
if rvField.IsValid() {
|
||||
dataMap[mapKey] = reflectValue.Field(i).Interface()
|
||||
} else {
|
||||
dataMap[mapKey] = nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No recursive map value converting
|
||||
if rvField.IsValid() {
|
||||
dataMap[mapKey] = reflectValue.Field(i).Interface()
|
||||
} else {
|
||||
dataMap[mapKey] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if !in.MustMapReturn && len(dataMap) == 0 {
|
||||
return in.Value
|
||||
}
|
||||
return dataMap
|
||||
|
||||
// The given value is type of slice.
|
||||
case reflect.Array, reflect.Slice:
|
||||
length := reflectValue.Len()
|
||||
if length == 0 {
|
||||
break
|
||||
}
|
||||
array := make([]interface{}, reflectValue.Len())
|
||||
for i := 0; i < length; i++ {
|
||||
array[i] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
IsRoot: false,
|
||||
Value: reflectValue.Index(i).Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
})
|
||||
}
|
||||
return array
|
||||
|
||||
default:
|
||||
}
|
||||
return in.Value
|
||||
}
|
||||
//// Map implements the map converting.
|
||||
//// It automatically checks and converts json string to map if `value` is string/[]byte.
|
||||
////
|
||||
//// TODO completely implement the recursive converting for all types, especially the map.
|
||||
//func (c *impConverter) Map(value any, option MapOption) (map[string]any, error) {
|
||||
// if value == nil {
|
||||
// return nil, nil
|
||||
// }
|
||||
// // It redirects to its underlying value if it has implemented interface iVal.
|
||||
// if v, ok := value.(localinterface.IVal); ok {
|
||||
// value = v.Val()
|
||||
// }
|
||||
// var (
|
||||
// newTags = gtag.StructTagPriority
|
||||
// )
|
||||
// switch len(option.Tags) {
|
||||
// case 0:
|
||||
// // No need handling.
|
||||
// case 1:
|
||||
// newTags = append(strings.Split(option.Tags[0], ","), gtag.StructTagPriority...)
|
||||
// default:
|
||||
// newTags = append(option.Tags, gtag.StructTagPriority...)
|
||||
// }
|
||||
// // Assert the common combination of types, and finally it uses reflection.
|
||||
// dataMap := make(map[string]any)
|
||||
// switch r := value.(type) {
|
||||
// case string:
|
||||
// // If it is a JSON string, automatically unmarshal it!
|
||||
// if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
|
||||
// if err := json.UnmarshalUseNumber([]byte(r), &dataMap); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// } else {
|
||||
// return nil, nil
|
||||
// }
|
||||
// case []byte:
|
||||
// // If it is a JSON string, automatically unmarshal it!
|
||||
// if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
|
||||
// if err := json.UnmarshalUseNumber(r, &dataMap); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// } else {
|
||||
// return nil, nil
|
||||
// }
|
||||
// case map[any]any:
|
||||
// recursiveOption := option
|
||||
// recursiveOption.Tags = newTags
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: v,
|
||||
// Recursive: option.Deep,
|
||||
// Option: recursiveOption,
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// case map[any]string:
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = v
|
||||
// }
|
||||
// case map[any]int:
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = v
|
||||
// }
|
||||
// case map[any]uint:
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = v
|
||||
// }
|
||||
// case map[any]float32:
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = v
|
||||
// }
|
||||
// case map[any]float64:
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = v
|
||||
// }
|
||||
// case map[string]bool:
|
||||
// for k, v := range r {
|
||||
// dataMap[k] = v
|
||||
// }
|
||||
// case map[string]int:
|
||||
// for k, v := range r {
|
||||
// dataMap[k] = v
|
||||
// }
|
||||
// case map[string]uint:
|
||||
// for k, v := range r {
|
||||
// dataMap[k] = v
|
||||
// }
|
||||
// case map[string]float32:
|
||||
// for k, v := range r {
|
||||
// dataMap[k] = v
|
||||
// }
|
||||
// case map[string]float64:
|
||||
// for k, v := range r {
|
||||
// dataMap[k] = v
|
||||
// }
|
||||
// case map[string]string:
|
||||
// for k, v := range r {
|
||||
// dataMap[k] = v
|
||||
// }
|
||||
// case map[string]any:
|
||||
// if option.Deep {
|
||||
// recursiveOption := option
|
||||
// recursiveOption.Tags = newTags
|
||||
// // A copy of current map.
|
||||
// for k, v := range r {
|
||||
// dataMap[k] = c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: v,
|
||||
// Recursive: option.Deep,
|
||||
// Option: recursiveOption,
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// } else {
|
||||
// // It returns the map directly without any changing.
|
||||
// return r, nil
|
||||
// }
|
||||
// case map[int]any:
|
||||
// recursiveOption := option
|
||||
// recursiveOption.Tags = newTags
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: v,
|
||||
// Recursive: option.Deep,
|
||||
// Option: recursiveOption,
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// case map[int]string:
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = v
|
||||
// }
|
||||
// case map[uint]string:
|
||||
// for k, v := range r {
|
||||
// dataMap[String(k)] = v
|
||||
// }
|
||||
//
|
||||
// default:
|
||||
// // Not a common type, it then uses reflection for conversion.
|
||||
// var reflectValue reflect.Value
|
||||
// if v, ok := value.(reflect.Value); ok {
|
||||
// reflectValue = v
|
||||
// } else {
|
||||
// reflectValue = reflect.ValueOf(value)
|
||||
// }
|
||||
// reflectKind := reflectValue.Kind()
|
||||
// // If it is a pointer, we should find its real data type.
|
||||
// for reflectKind == reflect.Ptr {
|
||||
// reflectValue = reflectValue.Elem()
|
||||
// reflectKind = reflectValue.Kind()
|
||||
// }
|
||||
// switch reflectKind {
|
||||
// // If `value` is type of array, it converts the value of even number index as its key and
|
||||
// // the value of odd number index as its corresponding value, for example:
|
||||
// // []string{"k1","v1","k2","v2"} => map[string]any{"k1":"v1", "k2":"v2"}
|
||||
// // []string{"k1","v1","k2"} => map[string]any{"k1":"v1", "k2":nil}
|
||||
// case reflect.Slice, reflect.Array:
|
||||
// length := reflectValue.Len()
|
||||
// for i := 0; i < length; i += 2 {
|
||||
// if i+1 < length {
|
||||
// dataMap[String(reflectValue.Index(i).Interface())] = reflectValue.Index(i + 1).Interface()
|
||||
// } else {
|
||||
// dataMap[String(reflectValue.Index(i).Interface())] = nil
|
||||
// }
|
||||
// }
|
||||
// case reflect.Map, reflect.Struct, reflect.Interface:
|
||||
// recursiveOption := option
|
||||
// recursiveOption.Tags = newTags
|
||||
// convertedValue := c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: true,
|
||||
// Value: value,
|
||||
// Recursive: option.Deep,
|
||||
// Option: recursiveOption,
|
||||
// MustMapReturn: option.EmptyEvenNil,
|
||||
// },
|
||||
// )
|
||||
// if m, ok := convertedValue.(map[string]any); ok {
|
||||
// return m, nil
|
||||
// }
|
||||
// return nil, nil
|
||||
// default:
|
||||
// return nil, nil
|
||||
// }
|
||||
// }
|
||||
// return dataMap, nil
|
||||
//}
|
||||
//
|
||||
//func getUsedMapOption(option ...MapOption) MapOption {
|
||||
// var usedOption MapOption
|
||||
// if len(option) > 0 {
|
||||
// usedOption = option[0]
|
||||
// }
|
||||
// return usedOption
|
||||
//}
|
||||
//
|
||||
//type doMapConvertForMapOrStructValueInput struct {
|
||||
// IsRoot bool // It returns directly if it is not root and with no recursive converting.
|
||||
// Value any // Current operation value.
|
||||
// Recursive bool // Whether convert recursively for `current` operation.
|
||||
// Option MapOption // Map converting option.
|
||||
// MustMapReturn bool // Must return map instead of Value when empty.
|
||||
//}
|
||||
//
|
||||
//func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) any {
|
||||
// if !in.IsRoot && !in.Recursive {
|
||||
// return in.Value
|
||||
// }
|
||||
//
|
||||
// var reflectValue reflect.Value
|
||||
// if v, ok := in.Value.(reflect.Value); ok {
|
||||
// reflectValue = v
|
||||
// in.Value = v.Interface()
|
||||
// } else {
|
||||
// reflectValue = reflect.ValueOf(in.Value)
|
||||
// }
|
||||
// reflectKind := reflectValue.Kind()
|
||||
// // If it is a pointer, we should find its real data type.
|
||||
// for reflectKind == reflect.Ptr {
|
||||
// reflectValue = reflectValue.Elem()
|
||||
// reflectKind = reflectValue.Kind()
|
||||
// }
|
||||
// switch reflectKind {
|
||||
// case reflect.Map:
|
||||
// var (
|
||||
// mapIter = reflectValue.MapRange()
|
||||
// dataMap = make(map[string]any)
|
||||
// )
|
||||
// for mapIter.Next() {
|
||||
// var (
|
||||
// mapKeyValue = mapIter.Value()
|
||||
// mapValue any
|
||||
// )
|
||||
// switch {
|
||||
// case mapKeyValue.IsZero():
|
||||
// if utils.CanCallIsNil(mapKeyValue) && mapKeyValue.IsNil() {
|
||||
// // quick check for nil value.
|
||||
// mapValue = nil
|
||||
// } else {
|
||||
// // in case of:
|
||||
// // exception recovered: reflect: call of reflect.Value.Interface on zero Value
|
||||
// mapValue = reflect.New(mapKeyValue.Type()).Elem().Interface()
|
||||
// }
|
||||
// default:
|
||||
// mapValue = mapKeyValue.Interface()
|
||||
// }
|
||||
// dataMap[String(mapIter.Key().Interface())] = c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: mapValue,
|
||||
// Recursive: in.Recursive,
|
||||
// Option: in.Option,
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// return dataMap
|
||||
//
|
||||
// case reflect.Struct:
|
||||
// var dataMap = make(map[string]any)
|
||||
// // Map converting interface check.
|
||||
// if v, ok := in.Value.(localinterface.IMapStrAny); ok {
|
||||
// // Value copy, in case of concurrent safety.
|
||||
// for mapK, mapV := range v.MapStrAny() {
|
||||
// if in.Recursive {
|
||||
// dataMap[mapK] = c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: mapV,
|
||||
// Recursive: in.Recursive,
|
||||
// Option: in.Option,
|
||||
// },
|
||||
// )
|
||||
// } else {
|
||||
// dataMap[mapK] = mapV
|
||||
// }
|
||||
// }
|
||||
// if len(dataMap) > 0 {
|
||||
// return dataMap
|
||||
// }
|
||||
// }
|
||||
// // Using reflect for converting.
|
||||
// var (
|
||||
// rtField reflect.StructField
|
||||
// rvField reflect.Value
|
||||
// reflectType = reflectValue.Type() // attribute value type.
|
||||
// mapKey = "" // mapKey may be the tag name or the struct attribute name.
|
||||
// )
|
||||
// for i := 0; i < reflectValue.NumField(); i++ {
|
||||
// rtField = reflectType.Field(i)
|
||||
// rvField = reflectValue.Field(i)
|
||||
// // Only convert the public attributes.
|
||||
// fieldName := rtField.Name
|
||||
// if !utils.IsLetterUpper(fieldName[0]) {
|
||||
// continue
|
||||
// }
|
||||
// mapKey = ""
|
||||
// fieldTag := rtField.Tag
|
||||
// for _, tag := range in.Option.Tags {
|
||||
// if mapKey = fieldTag.Get(tag); mapKey != "" {
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// if mapKey == "" {
|
||||
// mapKey = fieldName
|
||||
// } else {
|
||||
// // Support json tag feature: -, omitempty
|
||||
// mapKey = strings.TrimSpace(mapKey)
|
||||
// if mapKey == "-" {
|
||||
// continue
|
||||
// }
|
||||
// array := strings.Split(mapKey, ",")
|
||||
// if len(array) > 1 {
|
||||
// switch strings.TrimSpace(array[1]) {
|
||||
// case "omitempty":
|
||||
// if in.Option.OmitEmpty && empty.IsEmpty(rvField.Interface()) {
|
||||
// continue
|
||||
// } else {
|
||||
// mapKey = strings.TrimSpace(array[0])
|
||||
// }
|
||||
// default:
|
||||
// mapKey = strings.TrimSpace(array[0])
|
||||
// }
|
||||
// }
|
||||
// if mapKey == "" {
|
||||
// mapKey = fieldName
|
||||
// }
|
||||
// }
|
||||
// if in.Recursive || rtField.Anonymous {
|
||||
// // Do map converting recursively.
|
||||
// var (
|
||||
// rvAttrField = rvField
|
||||
// rvAttrKind = rvField.Kind()
|
||||
// )
|
||||
// if rvAttrKind == reflect.Ptr {
|
||||
// rvAttrField = rvField.Elem()
|
||||
// rvAttrKind = rvAttrField.Kind()
|
||||
// }
|
||||
// switch rvAttrKind {
|
||||
// case reflect.Struct:
|
||||
// // Embedded struct and has no fields, just ignores it.
|
||||
// // Eg: gmeta.Meta
|
||||
// if rvAttrField.Type().NumField() == 0 {
|
||||
// continue
|
||||
// }
|
||||
// var (
|
||||
// hasNoTag = mapKey == fieldName
|
||||
// // DO NOT use rvAttrField.Interface() here,
|
||||
// // as it might be changed from pointer to struct.
|
||||
// rvInterface = rvField.Interface()
|
||||
// )
|
||||
// switch {
|
||||
// case hasNoTag && rtField.Anonymous:
|
||||
// // It means this attribute field has no tag.
|
||||
// // Overwrite the attribute with sub-struct attribute fields.
|
||||
// anonymousValue := c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: rvInterface,
|
||||
// Recursive: true,
|
||||
// Option: in.Option,
|
||||
// })
|
||||
// if m, ok := anonymousValue.(map[string]any); ok {
|
||||
// for k, v := range m {
|
||||
// dataMap[k] = v
|
||||
// }
|
||||
// } else {
|
||||
// dataMap[mapKey] = rvInterface
|
||||
// }
|
||||
//
|
||||
// // It means this attribute field has desired tag.
|
||||
// case !hasNoTag && rtField.Anonymous:
|
||||
// dataMap[mapKey] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: rvInterface,
|
||||
// Recursive: true,
|
||||
// Option: in.Option,
|
||||
// })
|
||||
//
|
||||
// default:
|
||||
// dataMap[mapKey] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: rvInterface,
|
||||
// Recursive: in.Recursive,
|
||||
// Option: in.Option,
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// // The struct attribute is type of slice.
|
||||
// case reflect.Array, reflect.Slice:
|
||||
// length := rvAttrField.Len()
|
||||
// if length == 0 {
|
||||
// dataMap[mapKey] = rvAttrField.Interface()
|
||||
// break
|
||||
// }
|
||||
// array := make([]any, length)
|
||||
// for arrayIndex := 0; arrayIndex < length; arrayIndex++ {
|
||||
// array[arrayIndex] = c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: rvAttrField.Index(arrayIndex).Interface(),
|
||||
// Recursive: in.Recursive,
|
||||
// Option: in.Option,
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// dataMap[mapKey] = array
|
||||
// case reflect.Map:
|
||||
// var (
|
||||
// mapIter = rvAttrField.MapRange()
|
||||
// nestedMap = make(map[string]any)
|
||||
// )
|
||||
// for mapIter.Next() {
|
||||
// nestedMap[String(mapIter.Key().Interface())] = c.doMapConvertForMapOrStructValue(
|
||||
// doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: mapIter.Value().Interface(),
|
||||
// Recursive: in.Recursive,
|
||||
// Option: in.Option,
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
// dataMap[mapKey] = nestedMap
|
||||
// default:
|
||||
// if rvField.IsValid() {
|
||||
// dataMap[mapKey] = reflectValue.Field(i).Interface()
|
||||
// } else {
|
||||
// dataMap[mapKey] = nil
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// // No recursive map value converting
|
||||
// if rvField.IsValid() {
|
||||
// dataMap[mapKey] = reflectValue.Field(i).Interface()
|
||||
// } else {
|
||||
// dataMap[mapKey] = nil
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if !in.MustMapReturn && len(dataMap) == 0 {
|
||||
// return in.Value
|
||||
// }
|
||||
// return dataMap
|
||||
//
|
||||
// // The given value is type of slice.
|
||||
// case reflect.Array, reflect.Slice:
|
||||
// length := reflectValue.Len()
|
||||
// if length == 0 {
|
||||
// break
|
||||
// }
|
||||
// array := make([]any, reflectValue.Len())
|
||||
// for i := 0; i < length; i++ {
|
||||
// array[i] = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
|
||||
// IsRoot: false,
|
||||
// Value: reflectValue.Index(i).Interface(),
|
||||
// Recursive: in.Recursive,
|
||||
// Option: in.Option,
|
||||
// })
|
||||
// }
|
||||
// return array
|
||||
//
|
||||
// default:
|
||||
// }
|
||||
// return in.Value
|
||||
//}
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
// 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
|
||||
@ -23,7 +23,7 @@ import (
|
||||
//
|
||||
// The optional parameter `mapping` is used for struct attribute to map key mapping, which makes
|
||||
// sense only if the items of original map `params` is type struct.
|
||||
func (c *Converter) MapToMap(params any, pointer any, mapping ...map[string]string) (err error) {
|
||||
func (c *impConverter) MapToMap(params any, pointer any, mapping ...map[string]string) (err error) {
|
||||
var (
|
||||
paramsRv reflect.Value
|
||||
paramsKind reflect.Kind
|
||||
@ -98,27 +98,27 @@ func (c *Converter) MapToMap(params any, pointer any, mapping ...map[string]stri
|
||||
return err
|
||||
}
|
||||
default:
|
||||
mapValue.Set(
|
||||
reflect.ValueOf(
|
||||
c.doConvert(doConvertInput{
|
||||
FromValue: paramsRv.MapIndex(key).Interface(),
|
||||
ToTypeName: pointerValueType.String(),
|
||||
ReferValue: mapValue,
|
||||
Extra: nil,
|
||||
}),
|
||||
),
|
||||
)
|
||||
convertResult, err := c.doConvert(doConvertInput{
|
||||
FromValue: paramsRv.MapIndex(key).Interface(),
|
||||
ToTypeName: pointerValueType.String(),
|
||||
ReferValue: mapValue,
|
||||
Extra: nil,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mapValue.Set(reflect.ValueOf(convertResult))
|
||||
}
|
||||
var mapKey = reflect.ValueOf(
|
||||
c.doConvert(
|
||||
doConvertInput{
|
||||
FromValue: key.Interface(),
|
||||
ToTypeName: pointerKeyType.Name(),
|
||||
ReferValue: reflect.New(pointerKeyType).Elem().Interface(),
|
||||
Extra: nil,
|
||||
},
|
||||
),
|
||||
)
|
||||
convertResult, err := c.doConvert(doConvertInput{
|
||||
FromValue: key.Interface(),
|
||||
ToTypeName: pointerKeyType.Name(),
|
||||
ReferValue: reflect.New(pointerKeyType).Elem().Interface(),
|
||||
Extra: nil,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var mapKey = reflect.ValueOf(convertResult)
|
||||
dataMap.SetMapIndex(mapKey, mapValue)
|
||||
}
|
||||
pointerRv.Set(dataMap)
|
||||
|
||||
@ -21,7 +21,7 @@ import (
|
||||
//
|
||||
// The optional parameter `mapping` is used for struct attribute to map key mapping, which makes
|
||||
// sense only if the item of `params` is type struct.
|
||||
func (c *Converter) MapToMaps(params any, pointer any, paramKeyToAttrMap ...map[string]string) (err error) {
|
||||
func (c *impConverter) MapToMaps(params any, pointer any, paramKeyToAttrMap ...map[string]string) (err error) {
|
||||
// Params and its element type check.
|
||||
var (
|
||||
paramsRv reflect.Value
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
package gconv
|
||||
|
||||
func (c *Converter) Rune(any any) (rune, error) {
|
||||
func (c *impConverter) Rune(any any) (rune, error) {
|
||||
if v, ok := any.(rune); ok {
|
||||
return v, nil
|
||||
}
|
||||
@ -17,7 +17,7 @@ func (c *Converter) Rune(any any) (rune, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (c *Converter) Runes(any any) ([]rune, error) {
|
||||
func (c *impConverter) Runes(any any) ([]rune, error) {
|
||||
if v, ok := any.([]rune); ok {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *Converter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...map[string]string) (err error) {
|
||||
func (c *impConverter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...map[string]string) (err error) {
|
||||
// Check if srcValue is nil, in which case no conversion is needed
|
||||
if srcValue == nil {
|
||||
return nil
|
||||
@ -182,7 +182,7 @@ func (c *Converter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...map[
|
||||
// - dstPointer: The destination pointer to convert to
|
||||
// - dstPointerReflectType: The reflection type of the destination pointer
|
||||
// - paramKeyToAttrMap: Optional mapping between parameter keys and struct attribute names
|
||||
func (c *Converter) doScanForComplicatedTypes(
|
||||
func (c *impConverter) doScanForComplicatedTypes(
|
||||
srcValue, dstPointer any,
|
||||
dstPointerReflectType reflect.Type,
|
||||
paramKeyToAttrMap ...map[string]string,
|
||||
|
||||
142
util/gconv/gconv_converter_slice_any.go
Normal file
142
util/gconv/gconv_converter_slice_any.go
Normal file
@ -0,0 +1,142 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
type SliceOption struct {
|
||||
// FailBreak specifies whether to break converting the next element
|
||||
// if one element conversion fails in slice.
|
||||
FailBreak bool
|
||||
}
|
||||
|
||||
// SliceAny converts `any` to []any.
|
||||
func (c *impConverter) SliceAny(any interface{}, option SliceOption) ([]any, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
array []interface{}
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []interface{}:
|
||||
array = value
|
||||
case []string:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int8:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int16:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int32:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int64:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []uint:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
|
||||
case []uint16:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []uint32:
|
||||
for _, v := range value {
|
||||
array = append(array, v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []bool:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []float32:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []float64:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return v.Interfaces(), err
|
||||
}
|
||||
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]interface{}, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = originValueAndKind.OriginValue.Index(i).Interface()
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
return []interface{}{any}, err
|
||||
}
|
||||
}
|
||||
417
util/gconv/gconv_converter_slice_float.go
Normal file
417
util/gconv/gconv_converter_slice_float.go
Normal file
@ -0,0 +1,417 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceFloat32 converts `any` to []float32.
|
||||
func (c *impConverter) SliceFloat32(any interface{}, option SliceOption) ([]float32, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
f float32
|
||||
array []float32 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int8:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int16:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int32:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int64:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []float32{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
f, err = c.Float32(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []float32{f}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []bool:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []float32:
|
||||
array = value
|
||||
case []float64:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
if v, ok := any.(localinterface.IFloats); ok {
|
||||
return c.SliceFloat32(v.Floats(), option)
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceFloat32(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]float32, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
f, err = c.Float32(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = f
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []float32{}, err
|
||||
}
|
||||
f, err = c.Float32(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []float32{f}, err
|
||||
}
|
||||
}
|
||||
|
||||
// SliceFloat64 converts `any` to []float64.
|
||||
func (c *impConverter) SliceFloat64(any interface{}, option SliceOption) ([]float64, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
f float64
|
||||
array []float64 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int8:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int16:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int32:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []int64:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []float64{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
f, err = c.Float64(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []float64{f}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []bool:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []float32:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
case []float64:
|
||||
array = value
|
||||
case []interface{}:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
f, err = c.Float64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = f
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
if v, ok := any.(localinterface.IFloats); ok {
|
||||
return v.Floats(), err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceFloat64(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]float64, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
f, err = c.Float64(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = f
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []float64{}, err
|
||||
}
|
||||
f, err = c.Float64(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []float64{f}, err
|
||||
}
|
||||
}
|
||||
536
util/gconv/gconv_converter_slice_int.go
Normal file
536
util/gconv/gconv_converter_slice_int.go
Normal file
@ -0,0 +1,536 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceInt converts `any` to []int.
|
||||
func (c *impConverter) SliceInt(any any, option SliceOption) ([]int, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
ii int
|
||||
array []int = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []int:
|
||||
array = value
|
||||
case []int8:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []int{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
ii, err = c.Int(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []int{ii}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []float64:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInts); ok {
|
||||
return v.Ints(), err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceInt(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]int, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
ii, err = c.Int(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = ii
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []int{}, err
|
||||
}
|
||||
ii, err = c.Int(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []int{ii}, err
|
||||
}
|
||||
}
|
||||
|
||||
// SliceInt32 converts `any` to []int32.
|
||||
func (c *impConverter) SliceInt32(any any, option SliceOption) ([]int32, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
ii int32
|
||||
array []int32 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []int:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []int32:
|
||||
array = value
|
||||
case []int64:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []int32{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
ii, err = c.Int32(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []int32{ii}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []float64:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInts); ok {
|
||||
return c.SliceInt32(v.Ints(), option)
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceInt32(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]int32, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
ii, err = c.Int32(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = ii
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []int32{}, err
|
||||
}
|
||||
ii, err = c.Int32(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []int32{ii}, err
|
||||
}
|
||||
}
|
||||
|
||||
// SliceInt64 converts `any` to []int64.
|
||||
func (c *impConverter) SliceInt64(any any, option SliceOption) ([]int64, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
ii int64
|
||||
array []int64 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []int:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int64:
|
||||
array = value
|
||||
case []uint:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []int64{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
ii, err = c.Int64(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []int64{ii}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []float64:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
ii, err = c.Int64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ii
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInts); ok {
|
||||
return c.SliceInt64(v.Ints(), option)
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceInt64(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]int64, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
ii, err = c.Int64(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = ii
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []int64{}, err
|
||||
}
|
||||
ii, err = c.Int64(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []int64{ii}, err
|
||||
}
|
||||
}
|
||||
59
util/gconv/gconv_converter_slice_map.go
Normal file
59
util/gconv/gconv_converter_slice_map.go
Normal file
@ -0,0 +1,59 @@
|
||||
// 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 "github.com/gogf/gf/v2/internal/json"
|
||||
|
||||
// SliceMap converts `value` to []map[string]any.
|
||||
// Note that it automatically checks and converts json string to []map if `value` is string/[]byte.
|
||||
func (c *impConverter) SliceMap(value any, sliceOption SliceOption, mapOption MapOption) ([]map[string]any, error) {
|
||||
if value == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch r := value.(type) {
|
||||
case string:
|
||||
list := make([]map[string]any, 0)
|
||||
if len(r) > 0 && r[0] == '[' && r[len(r)-1] == ']' {
|
||||
if err := json.UnmarshalUseNumber([]byte(r), &list); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
case []byte:
|
||||
list := make([]map[string]any, 0)
|
||||
if len(r) > 0 && r[0] == '[' && r[len(r)-1] == ']' {
|
||||
if err := json.UnmarshalUseNumber(r, &list); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
case []map[string]any:
|
||||
return r, nil
|
||||
|
||||
default:
|
||||
array, err := c.SliceAny(value, sliceOption)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(array) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
list := make([]map[string]any, len(array))
|
||||
for k, v := range array {
|
||||
m := Map(v, mapOption)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
list[k] = m
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
}
|
||||
216
util/gconv/gconv_converter_slice_str.go
Normal file
216
util/gconv/gconv_converter_slice_str.go
Normal file
@ -0,0 +1,216 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceStr converts `any` to []string.
|
||||
func (c *impConverter) SliceStr(any interface{}, option SliceOption) ([]string, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
s string
|
||||
array []string = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []int:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []int8:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []int32:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []int64:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []uint:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
return array, err
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []string{}, err
|
||||
}
|
||||
return []string{value}, err
|
||||
case []uint16:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []bool:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []float32:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []float64:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []string:
|
||||
array = value
|
||||
case [][]byte:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
if v, ok := any.(localinterface.IStrings); ok {
|
||||
return v.Strings(), err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceStr(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]string, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
s, err = c.String(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = s
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []string{}, err
|
||||
}
|
||||
s, err = c.String(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []string{s}, err
|
||||
}
|
||||
}
|
||||
527
util/gconv/gconv_converter_slice_uint.go
Normal file
527
util/gconv/gconv_converter_slice_uint.go
Normal file
@ -0,0 +1,527 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceUint converts `any` to []uint.
|
||||
func (c *impConverter) SliceUint(any interface{}, option SliceOption) ([]uint, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
ui uint
|
||||
array []uint = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []int8:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []uint:
|
||||
array = value
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []uint{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
ui, err = c.Uint(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []uint{ui}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []float64:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
}
|
||||
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
|
||||
// Default handler.
|
||||
if v, ok := any.(localinterface.IUints); ok {
|
||||
return v.Uints(), err
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceUint(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]uint, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
ui, err = c.Uint(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = ui
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []uint{}, err
|
||||
}
|
||||
ui, err = c.Uint(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []uint{ui}, err
|
||||
}
|
||||
}
|
||||
|
||||
// SliceUint32 converts `any` to []uint32.
|
||||
func (c *impConverter) SliceUint32(any interface{}, option SliceOption) ([]uint32, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
ui uint32
|
||||
array []uint32 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []int8:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []uint32{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
ui, err = c.Uint32(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []uint32{ui}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = value
|
||||
case []uint64:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []float64:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint32(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
|
||||
// Default handler.
|
||||
if v, ok := any.(localinterface.IUints); ok {
|
||||
return c.SliceUint32(v.Uints(), option)
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceUint32(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]uint32, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
ui, err = c.Uint32(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = ui
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []uint32{}, err
|
||||
}
|
||||
ui, err = c.Uint32(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []uint32{ui}, err
|
||||
}
|
||||
}
|
||||
|
||||
// SliceUint64 converts `any` to []uint64.
|
||||
func (c *impConverter) SliceUint64(any interface{}, option SliceOption) ([]uint64, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
err error
|
||||
ui uint64
|
||||
array []uint64 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []int8:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if err = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array, err
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []uint64{}, err
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
ui, err = c.Uint64(value)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []uint64{ui}, err
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = value
|
||||
case []bool:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []float64:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
ui, err = c.Uint64(v)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = ui
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array, err
|
||||
}
|
||||
// Default handler.
|
||||
if v, ok := any.(localinterface.IUints); ok {
|
||||
return c.SliceUint64(v.Uints(), option)
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return c.SliceUint64(v.Interfaces(), option)
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]uint64, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
ui, err = c.Uint64(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
slice[i] = ui
|
||||
}
|
||||
return slice, err
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []uint64{}, err
|
||||
}
|
||||
ui, err = c.Uint64(any)
|
||||
if err != nil && option.FailBreak {
|
||||
return nil, err
|
||||
}
|
||||
return []uint64{ui}, err
|
||||
}
|
||||
}
|
||||
@ -20,7 +20,7 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *Converter) String(any any) (string, error) {
|
||||
func (c *impConverter) String(any any) (string, error) {
|
||||
if empty.IsNil(any) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
// Struct is the core internal converting function for any data to struct.
|
||||
func (c *Converter) Struct(
|
||||
func (c *impConverter) Struct(
|
||||
params any,
|
||||
pointer any,
|
||||
paramKeyToAttrMap map[string]string,
|
||||
@ -147,7 +147,7 @@ func (c *Converter) Struct(
|
||||
return nil
|
||||
}
|
||||
// Get struct info from cache or parse struct and cache the struct info.
|
||||
cachedStructInfo := c.internalConvertConfig.GetCachedStructInfo(
|
||||
cachedStructInfo := c.internalConverter.GetCachedStructInfo(
|
||||
pointerElemReflectValue.Type(), priorityTag,
|
||||
)
|
||||
// Nothing to be converted.
|
||||
@ -204,7 +204,7 @@ func (c *Converter) Struct(
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Converter) setOtherSameNameField(
|
||||
func (c *impConverter) setOtherSameNameField(
|
||||
cachedFieldInfo *structcache.CachedFieldInfo,
|
||||
srcValue any,
|
||||
structValue reflect.Value,
|
||||
@ -220,7 +220,7 @@ func (c *Converter) setOtherSameNameField(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Converter) bindStructWithLoopFieldInfos(
|
||||
func (c *impConverter) bindStructWithLoopFieldInfos(
|
||||
paramsMap map[string]any,
|
||||
structValue reflect.Value,
|
||||
paramKeyToAttrMap map[string]string,
|
||||
@ -316,7 +316,7 @@ func fuzzyMatchingFieldName(
|
||||
|
||||
// bindVarToStructField sets value to struct object attribute by name.
|
||||
// each value to attribute converting comes into in this function.
|
||||
func (c *Converter) bindVarToStructField(
|
||||
func (c *impConverter) bindVarToStructField(
|
||||
cachedFieldInfo *structcache.CachedFieldInfo,
|
||||
fieldValue reflect.Value,
|
||||
srcValue any,
|
||||
@ -439,7 +439,7 @@ func bindVarToReflectValueWithInterfaceCheck(reflectValue reflect.Value, value a
|
||||
}
|
||||
|
||||
// bindVarToReflectValue sets `value` to reflect value object `structFieldValue`.
|
||||
func (c *Converter) bindVarToReflectValue(
|
||||
func (c *impConverter) bindVarToReflectValue(
|
||||
structFieldValue reflect.Value, value any, paramKeyToAttrMap map[string]string,
|
||||
) (err error) {
|
||||
// JSON content converting.
|
||||
|
||||
@ -20,7 +20,7 @@ import (
|
||||
// The parameter `pointer` should be type of pointer to slice of struct.
|
||||
// Note that if `pointer` is a pointer to another pointer of type of slice of struct,
|
||||
// it will create the struct/pointer internally.
|
||||
func (c *Converter) Structs(
|
||||
func (c *impConverter) Structs(
|
||||
params any, pointer any, paramKeyToAttrMap map[string]string, priorityTag string,
|
||||
) (err error) {
|
||||
defer func() {
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
// Time converts `any` to time.Time.
|
||||
func (c *Converter) Time(any interface{}, format ...string) (time.Time, error) {
|
||||
func (c *impConverter) Time(any interface{}, format ...string) (time.Time, error) {
|
||||
// It's already this type.
|
||||
if len(format) == 0 {
|
||||
if v, ok := any.(time.Time); ok {
|
||||
@ -36,7 +36,7 @@ func (c *Converter) Time(any interface{}, format ...string) (time.Time, error) {
|
||||
// Duration converts `any` to time.Duration.
|
||||
// If `any` is string, then it uses time.ParseDuration to convert it.
|
||||
// If `any` is numeric, then it converts `any` as nanoseconds.
|
||||
func (c *Converter) Duration(any interface{}) (time.Duration, error) {
|
||||
func (c *impConverter) Duration(any interface{}) (time.Duration, error) {
|
||||
// It's already this type.
|
||||
if v, ok := any.(time.Duration); ok {
|
||||
return v, nil
|
||||
@ -60,7 +60,7 @@ func (c *Converter) Duration(any interface{}) (time.Duration, error) {
|
||||
// It returns the converted value that matched the first format of the formats slice.
|
||||
// If no `format` given, it converts `any` using gtime.NewFromTimeStamp if `any` is numeric,
|
||||
// or using gtime.StrToTime if `any` is string.
|
||||
func (c *Converter) GTime(any interface{}, format ...string) (*gtime.Time, error) {
|
||||
func (c *impConverter) GTime(any interface{}, format ...string) (*gtime.Time, error) {
|
||||
if empty.IsNil(any) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *Converter) Uint(any any) (uint, error) {
|
||||
func (c *impConverter) Uint(any any) (uint, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
@ -29,7 +29,7 @@ func (c *Converter) Uint(any any) (uint, error) {
|
||||
return uint(v), err
|
||||
}
|
||||
|
||||
func (c *Converter) Uint8(any any) (uint8, error) {
|
||||
func (c *impConverter) Uint8(any any) (uint8, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
@ -40,7 +40,7 @@ func (c *Converter) Uint8(any any) (uint8, error) {
|
||||
return uint8(v), err
|
||||
}
|
||||
|
||||
func (c *Converter) Uint16(any any) (uint16, error) {
|
||||
func (c *impConverter) Uint16(any any) (uint16, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
@ -51,7 +51,7 @@ func (c *Converter) Uint16(any any) (uint16, error) {
|
||||
return uint16(v), err
|
||||
}
|
||||
|
||||
func (c *Converter) Uint32(any any) (uint32, error) {
|
||||
func (c *impConverter) Uint32(any any) (uint32, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
@ -62,7 +62,7 @@ func (c *Converter) Uint32(any any) (uint32, error) {
|
||||
return uint32(v), err
|
||||
}
|
||||
|
||||
func (c *Converter) Uint64(any any) (uint64, error) {
|
||||
func (c *impConverter) Uint64(any any) (uint64, error) {
|
||||
if empty.IsNil(any) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@ -6,17 +6,6 @@
|
||||
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceAny is alias of Interfaces.
|
||||
func SliceAny(any interface{}) []interface{} {
|
||||
return Interfaces(any)
|
||||
@ -24,123 +13,6 @@ func SliceAny(any interface{}) []interface{} {
|
||||
|
||||
// Interfaces converts `any` to []interface{}.
|
||||
func Interfaces(any interface{}) []interface{} {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var array []interface{}
|
||||
switch value := any.(type) {
|
||||
case []interface{}:
|
||||
array = value
|
||||
case []string:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int8:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int16:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int32:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []int64:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []uint:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
case []uint16:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []uint32:
|
||||
for _, v := range value {
|
||||
array = append(array, v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []bool:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []float32:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
case []float64:
|
||||
array = make([]interface{}, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = v
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return v.Interfaces()
|
||||
}
|
||||
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]interface{}, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = originValueAndKind.OriginValue.Index(i).Interface()
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
return []interface{}{any}
|
||||
}
|
||||
result, _ := defaultConverter.SliceAny(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -6,18 +6,6 @@
|
||||
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceFloat is alias of Floats.
|
||||
func SliceFloat(any interface{}) []float64 {
|
||||
return Floats(any)
|
||||
@ -40,270 +28,12 @@ func Floats(any interface{}) []float64 {
|
||||
|
||||
// Float32s converts `any` to []float32.
|
||||
func Float32s(any interface{}) []float32 {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []float32 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []int:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []uint:
|
||||
for _, v := range value {
|
||||
array = append(array, Float32(v))
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []float32{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []float32{Float32(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []float32:
|
||||
array = value
|
||||
case []float64:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]float32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float32(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
if v, ok := any.(localinterface.IFloats); ok {
|
||||
return Float32s(v.Floats())
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Float32s(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]float32, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Float32(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []float32{}
|
||||
}
|
||||
return []float32{Float32(any)}
|
||||
}
|
||||
result, _ := defaultConverter.SliceFloat32(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
// Float64s converts `any` to []float64.
|
||||
func Float64s(any interface{}) []float64 {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []float64 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []int:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []uint:
|
||||
for _, v := range value {
|
||||
array = append(array, Float64(v))
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []float64{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []float64{Float64(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []float32:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
case []float64:
|
||||
array = value
|
||||
case []interface{}:
|
||||
array = make([]float64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Float64(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
if v, ok := any.(localinterface.IFloats); ok {
|
||||
return v.Floats()
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Floats(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]float64, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Float64(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []float64{}
|
||||
}
|
||||
return []float64{Float64(any)}
|
||||
}
|
||||
result, _ := defaultConverter.SliceFloat64(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -6,464 +6,35 @@
|
||||
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceInt is alias of Ints.
|
||||
func SliceInt(any interface{}) []int {
|
||||
func SliceInt(any any) []int {
|
||||
return Ints(any)
|
||||
}
|
||||
|
||||
// SliceInt32 is alias of Int32s.
|
||||
func SliceInt32(any interface{}) []int32 {
|
||||
func SliceInt32(any any) []int32 {
|
||||
return Int32s(any)
|
||||
}
|
||||
|
||||
// SliceInt64 is alias of Int64s.
|
||||
func SliceInt64(any interface{}) []int64 {
|
||||
func SliceInt64(any any) []int64 {
|
||||
return Int64s(any)
|
||||
}
|
||||
|
||||
// Ints converts `any` to []int.
|
||||
func Ints(any interface{}) []int {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []int = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int(v)
|
||||
}
|
||||
case []int:
|
||||
array = value
|
||||
case []int8:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []int{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []int{Int(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int(v)
|
||||
}
|
||||
case []float64:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int(v)
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]int, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
if v, ok := any.(localinterface.IInts); ok {
|
||||
return v.Ints()
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Ints(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]int, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Int(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []int{}
|
||||
}
|
||||
return []int{Int(any)}
|
||||
}
|
||||
func Ints(any any) []int {
|
||||
result, _ := defaultConverter.SliceInt(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
// Int32s converts `any` to []int32.
|
||||
func Int32s(any interface{}) []int32 {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []int32 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int32(v)
|
||||
}
|
||||
case []int:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []int32:
|
||||
array = value
|
||||
case []int64:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []int32{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []int32{Int32(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int32(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int32(v)
|
||||
}
|
||||
case []float64:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int32(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int32(v)
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]int32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int32(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
if v, ok := any.(localinterface.IInts); ok {
|
||||
return Int32s(v.Ints())
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Int32s(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]int32, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Int32(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []int32{}
|
||||
}
|
||||
return []int32{Int32(any)}
|
||||
}
|
||||
func Int32s(any any) []int32 {
|
||||
result, _ := defaultConverter.SliceInt32(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
// Int64s converts `any` to []int64.
|
||||
func Int64s(any interface{}) []int64 {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []int64 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int64(v)
|
||||
}
|
||||
case []int:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []int64:
|
||||
array = value
|
||||
case []uint:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []int64{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []int64{Int64(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = int64(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int64(v)
|
||||
}
|
||||
case []float64:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int64(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int64(v)
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]int64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Int64(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
if v, ok := any.(localinterface.IInts); ok {
|
||||
return Int64s(v.Ints())
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Int64s(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]int64, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Int64(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []int64{}
|
||||
}
|
||||
return []int64{Int64(any)}
|
||||
}
|
||||
func Int64s(any any) []int64 {
|
||||
result, _ := defaultConverter.SliceInt64(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -6,17 +6,6 @@
|
||||
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceStr is alias of Strings.
|
||||
func SliceStr(any interface{}) []string {
|
||||
return Strings(any)
|
||||
@ -24,140 +13,6 @@ func SliceStr(any interface{}) []string {
|
||||
|
||||
// Strings converts `any` to []string.
|
||||
func Strings(any interface{}) []string {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []string = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []int:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
return array
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []string{}
|
||||
}
|
||||
return []string{value}
|
||||
case []uint16:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []float32:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []float64:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
case []string:
|
||||
array = value
|
||||
case [][]byte:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
if v, ok := any.(localinterface.IStrings); ok {
|
||||
return v.Strings()
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Strings(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]string, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = String(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []string{}
|
||||
}
|
||||
return []string{String(any)}
|
||||
}
|
||||
result, _ := defaultConverter.SliceStr(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -6,18 +6,6 @@
|
||||
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/reflection"
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
// SliceUint is alias of Uints.
|
||||
func SliceUint(any interface{}) []uint {
|
||||
return Uints(any)
|
||||
@ -35,426 +23,18 @@ func SliceUint64(any interface{}) []uint64 {
|
||||
|
||||
// Uints converts `any` to []uint.
|
||||
func Uints(any interface{}) []uint {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []uint = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []uint:
|
||||
array = value
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []uint{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []uint{Uint(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint(v)
|
||||
}
|
||||
case []float64:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint(v)
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]uint, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint(v)
|
||||
}
|
||||
}
|
||||
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
|
||||
// Default handler.
|
||||
if v, ok := any.(localinterface.IUints); ok {
|
||||
return v.Uints()
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Uints(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]uint, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Uint(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []uint{}
|
||||
}
|
||||
return []uint{Uint(any)}
|
||||
}
|
||||
result, _ := defaultConverter.SliceUint(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
// Uint32s converts `any` to []uint32.
|
||||
func Uint32s(any interface{}) []uint32 {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []uint32 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint32(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []uint32{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []uint32{Uint32(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = value
|
||||
case []uint64:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint32(v)
|
||||
}
|
||||
case []bool:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint32(v)
|
||||
}
|
||||
case []float64:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint32(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint32(v)
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]uint32, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint32(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
|
||||
// Default handler.
|
||||
if v, ok := any.(localinterface.IUints); ok {
|
||||
return Uint32s(v.Uints())
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Uint32s(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]uint32, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Uint32(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []uint32{}
|
||||
}
|
||||
return []uint32{Uint32(any)}
|
||||
}
|
||||
result, _ := defaultConverter.SliceUint32(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
// Uint64s converts `any` to []uint64.
|
||||
func Uint64s(any interface{}) []uint64 {
|
||||
if empty.IsNil(any) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
array []uint64 = nil
|
||||
)
|
||||
switch value := any.(type) {
|
||||
case []string:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint64(v)
|
||||
}
|
||||
case []int8:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []int16:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []int32:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []int64:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint8:
|
||||
if json.Valid(value) {
|
||||
if _ = json.UnmarshalUseNumber(value, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if bytes.EqualFold([]byte("null"), value) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case string:
|
||||
byteValue := []byte(value)
|
||||
if json.Valid(byteValue) {
|
||||
if _ = json.UnmarshalUseNumber(byteValue, &array); array != nil {
|
||||
return array
|
||||
}
|
||||
if strings.EqualFold(value, "null") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if value == "" {
|
||||
return []uint64{}
|
||||
}
|
||||
if utils.IsNumeric(value) {
|
||||
return []uint64{Uint64(value)}
|
||||
}
|
||||
case []uint16:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint32:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = uint64(v)
|
||||
}
|
||||
case []uint64:
|
||||
array = value
|
||||
case []bool:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
if v {
|
||||
array[k] = 1
|
||||
} else {
|
||||
array[k] = 0
|
||||
}
|
||||
}
|
||||
case []float32:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint64(v)
|
||||
}
|
||||
case []float64:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint64(v)
|
||||
}
|
||||
case []interface{}:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint64(v)
|
||||
}
|
||||
case [][]byte:
|
||||
array = make([]uint64, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = Uint64(v)
|
||||
}
|
||||
}
|
||||
if array != nil {
|
||||
return array
|
||||
}
|
||||
// Default handler.
|
||||
if v, ok := any.(localinterface.IUints); ok {
|
||||
return Uint64s(v.Uints())
|
||||
}
|
||||
if v, ok := any.(localinterface.IInterfaces); ok {
|
||||
return Uint64s(v.Interfaces())
|
||||
}
|
||||
// Not a common type, it then uses reflection for conversion.
|
||||
originValueAndKind := reflection.OriginValueAndKind(any)
|
||||
switch originValueAndKind.OriginKind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
var (
|
||||
length = originValueAndKind.OriginValue.Len()
|
||||
slice = make([]uint64, length)
|
||||
)
|
||||
for i := 0; i < length; i++ {
|
||||
slice[i] = Uint64(originValueAndKind.OriginValue.Index(i).Interface())
|
||||
}
|
||||
return slice
|
||||
|
||||
default:
|
||||
if originValueAndKind.OriginValue.IsZero() {
|
||||
return []uint64{}
|
||||
}
|
||||
return []uint64{Uint64(any)}
|
||||
}
|
||||
result, _ := defaultConverter.SliceUint64(any, SliceOption{})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -14,10 +14,8 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
type AnyConvertFunc func(from any, to reflect.Value) error
|
||||
|
||||
// ConvertConfig is the configuration for type converting.
|
||||
type ConvertConfig struct {
|
||||
// Converter is the configuration for type converting.
|
||||
type Converter struct {
|
||||
// map[reflect.Type]*CachedStructInfo
|
||||
cachedStructsInfoMap sync.Map
|
||||
|
||||
@ -28,9 +26,12 @@ type ConvertConfig struct {
|
||||
anyToTypeConvertMap map[reflect.Type]AnyConvertFunc
|
||||
}
|
||||
|
||||
// NewConvertConfig creates and returns a new ConvertConfig object.
|
||||
func NewConvertConfig() *ConvertConfig {
|
||||
return &ConvertConfig{
|
||||
// AnyConvertFunc is the function type for converting any to specified type.
|
||||
type AnyConvertFunc func(from any, to reflect.Value) error
|
||||
|
||||
// NewConverter creates and returns a new Converter object.
|
||||
func NewConverter() *Converter {
|
||||
return &Converter{
|
||||
cachedStructsInfoMap: sync.Map{},
|
||||
typeConverterFuncMap: make(map[reflect.Type]struct{}),
|
||||
anyToTypeConvertMap: make(map[reflect.Type]AnyConvertFunc),
|
||||
@ -38,7 +39,7 @@ func NewConvertConfig() *ConvertConfig {
|
||||
}
|
||||
|
||||
// RegisterTypeConvertFunc registers converting function for custom type.
|
||||
func (cf *ConvertConfig) RegisterTypeConvertFunc(fieldType reflect.Type) {
|
||||
func (cf *Converter) RegisterTypeConvertFunc(fieldType reflect.Type) {
|
||||
if fieldType.Kind() == reflect.Ptr {
|
||||
fieldType = fieldType.Elem()
|
||||
}
|
||||
@ -46,7 +47,7 @@ func (cf *ConvertConfig) RegisterTypeConvertFunc(fieldType reflect.Type) {
|
||||
}
|
||||
|
||||
// RegisterAnyConvertFunc registers custom type converting function for specified type.
|
||||
func (cf *ConvertConfig) RegisterAnyConvertFunc(t reflect.Type, convertFunc AnyConvertFunc) {
|
||||
func (cf *Converter) RegisterAnyConvertFunc(t reflect.Type, convertFunc AnyConvertFunc) {
|
||||
cf.anyToTypeConvertMap[t] = convertFunc
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
|
||||
// GetCachedStructInfo retrieves or parses and returns a cached info for certain struct type.
|
||||
// The given `structType` should be type of struct.
|
||||
func (cf *ConvertConfig) GetCachedStructInfo(structType reflect.Type, priorityTag string) *CachedStructInfo {
|
||||
func (cf *Converter) GetCachedStructInfo(structType reflect.Type, priorityTag string) *CachedStructInfo {
|
||||
if structType.Kind() != reflect.Struct {
|
||||
return nil
|
||||
}
|
||||
@ -44,12 +44,12 @@ func (cf *ConvertConfig) GetCachedStructInfo(structType reflect.Type, priorityTa
|
||||
return cachedStructInfo
|
||||
}
|
||||
|
||||
func (cf *ConvertConfig) storeCachedStructInfo(structType reflect.Type, cachedStructInfo *CachedStructInfo) {
|
||||
func (cf *Converter) storeCachedStructInfo(structType reflect.Type, cachedStructInfo *CachedStructInfo) {
|
||||
// Temporarily enabled as an experimental feature
|
||||
cf.cachedStructsInfoMap.Store(structType, cachedStructInfo)
|
||||
}
|
||||
|
||||
func (cf *ConvertConfig) getCachedConvertStructInfo(structType reflect.Type) (*CachedStructInfo, bool) {
|
||||
func (cf *Converter) getCachedConvertStructInfo(structType reflect.Type) (*CachedStructInfo, bool) {
|
||||
// Temporarily enabled as an experimental feature
|
||||
v, ok := cf.cachedStructsInfoMap.Load(structType)
|
||||
if ok {
|
||||
@ -60,7 +60,7 @@ func (cf *ConvertConfig) getCachedConvertStructInfo(structType reflect.Type) (*C
|
||||
|
||||
// parseStructToCachedStructInfo parses given struct reflection type and stores its fields info into given CachedStructInfo.
|
||||
// It stores nothing into CachedStructInfo if given struct reflection type has no fields.
|
||||
func (cf *ConvertConfig) parseStructToCachedStructInfo(
|
||||
func (cf *Converter) parseStructToCachedStructInfo(
|
||||
structType reflect.Type,
|
||||
fieldIndexes []int,
|
||||
cachedStructInfo *CachedStructInfo,
|
||||
|
||||
Reference in New Issue
Block a user