mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
up
This commit is contained in:
@ -10,21 +10,16 @@
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/converter"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/structcache"
|
||||
)
|
||||
|
||||
type AnyConvertFunc = structcache.AnyConvertFunc
|
||||
|
||||
var (
|
||||
// Empty strings.
|
||||
emptyStringMap = map[string]struct{}{
|
||||
"": {},
|
||||
"0": {},
|
||||
"no": {},
|
||||
"off": {},
|
||||
"false": {},
|
||||
}
|
||||
type (
|
||||
AnyConvertFunc = structcache.AnyConvertFunc
|
||||
MapOption = converter.MapOption
|
||||
ScanOption = converter.ScanOption
|
||||
SliceOption = converter.SliceOption
|
||||
)
|
||||
|
||||
// IUnmarshalValue is the interface for custom defined types customizing value assignment.
|
||||
@ -33,7 +28,7 @@ type IUnmarshalValue = localinterface.IUnmarshalValue
|
||||
|
||||
var (
|
||||
// defaultConverter is the default management object converting.
|
||||
defaultConverter = NewConverter()
|
||||
defaultConverter = converter.NewConverter()
|
||||
)
|
||||
|
||||
// RegisterConverter registers custom converter.
|
||||
|
||||
@ -6,23 +6,12 @@
|
||||
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Convert converts the variable `fromValue` to the type `toTypeName`, the type `toTypeName` is specified by string.
|
||||
//
|
||||
// The optional parameter `extraParams` is used for additional necessary parameter for this conversion.
|
||||
// It supports common basic types conversion as its conversion based on type name string.
|
||||
func Convert(fromValue any, toTypeName string, extraParams ...any) any {
|
||||
result, _ := defaultConverter.doConvert(
|
||||
doConvertInput{
|
||||
FromValue: fromValue,
|
||||
ToTypeName: toTypeName,
|
||||
ReferValue: nil,
|
||||
Extra: extraParams,
|
||||
},
|
||||
)
|
||||
result, _ := defaultConverter.ConvertWithTypeName(fromValue, toTypeName, extraParams...)
|
||||
return result
|
||||
}
|
||||
|
||||
@ -31,17 +20,6 @@ func Convert(fromValue any, toTypeName string, extraParams ...any) any {
|
||||
// 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 ConvertWithRefer(fromValue any, referValue any, extraParams ...any) any {
|
||||
var referValueRf reflect.Value
|
||||
if v, ok := referValue.(reflect.Value); ok {
|
||||
referValueRf = v
|
||||
} else {
|
||||
referValueRf = reflect.ValueOf(referValue)
|
||||
}
|
||||
result, _ := defaultConverter.doConvert(doConvertInput{
|
||||
FromValue: fromValue,
|
||||
ToTypeName: referValueRf.Type().String(),
|
||||
ReferValue: referValue,
|
||||
Extra: extraParams,
|
||||
})
|
||||
result, _ := defaultConverter.ConvertWithRefer(fromValue, referValue, extraParams...)
|
||||
return result
|
||||
}
|
||||
|
||||
@ -6,13 +6,6 @@
|
||||
|
||||
package gconv
|
||||
|
||||
type recursiveType string
|
||||
|
||||
const (
|
||||
recursiveTypeAuto recursiveType = "auto"
|
||||
recursiveTypeTrue recursiveType = "true"
|
||||
)
|
||||
|
||||
// Map converts any variable `value` to map[string]any. If the parameter `value` is not a
|
||||
// map/struct/*struct type, then the conversion will fail and returns nil.
|
||||
//
|
||||
@ -62,3 +55,11 @@ func MapStrStrDeep(value any, tags ...string) map[string]string {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getUsedMapOption(option ...MapOption) MapOption {
|
||||
var usedOption MapOption
|
||||
if len(option) > 0 {
|
||||
usedOption = option[0]
|
||||
}
|
||||
return usedOption
|
||||
}
|
||||
|
||||
@ -17,5 +17,9 @@ package gconv
|
||||
// The `paramKeyToAttrMap` parameter is used for mapping between attribute names and parameter keys.
|
||||
// TODO: change `paramKeyToAttrMap` to `ScanOption` to be more scalable; add `DeepCopy` option for `ScanOption`.
|
||||
func Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...map[string]string) (err error) {
|
||||
return defaultConverter.Scan(srcValue, dstPointer, paramKeyToAttrMap...)
|
||||
option := ScanOption{}
|
||||
if len(paramKeyToAttrMap) > 0 {
|
||||
option.ParamKeyToAttrMap = paramKeyToAttrMap[0]
|
||||
}
|
||||
return defaultConverter.Scan(srcValue, dstPointer, option)
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -16,6 +16,15 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/structcache"
|
||||
)
|
||||
|
||||
type AnyConvertFunc = structcache.AnyConvertFunc
|
||||
|
||||
type RecursiveType string
|
||||
|
||||
const (
|
||||
RecursiveTypeAuto RecursiveType = "auto"
|
||||
RecursiveTypeTrue RecursiveType = "true"
|
||||
)
|
||||
|
||||
type (
|
||||
converterInType = reflect.Type
|
||||
converterOutType = reflect.Type
|
||||
@ -66,6 +75,15 @@ type impConverter struct {
|
||||
}
|
||||
|
||||
var (
|
||||
// Empty strings.
|
||||
emptyStringMap = map[string]struct{}{
|
||||
"": {},
|
||||
"0": {},
|
||||
"no": {},
|
||||
"off": {},
|
||||
"false": {},
|
||||
}
|
||||
|
||||
intType = reflect.TypeOf(0)
|
||||
int8Type = reflect.TypeOf(int8(0))
|
||||
int16Type = reflect.TypeOf(int16(0))
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"math"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -14,6 +14,40 @@ import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ConvertWithTypeName converts the variable `fromValue` to the type `toTypeName`, the type `toTypeName` is specified by string.
|
||||
//
|
||||
// The optional parameter `extraParams` is used for additional necessary parameter for this conversion.
|
||||
// It supports common basic types conversion as its conversion based on type name string.
|
||||
func (c *impConverter) ConvertWithTypeName(fromValue any, toTypeName string, extraParams ...any) (any, error) {
|
||||
return c.doConvert(
|
||||
doConvertInput{
|
||||
FromValue: fromValue,
|
||||
ToTypeName: toTypeName,
|
||||
ReferValue: nil,
|
||||
Extra: extraParams,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// ConvertWithRefer converts the variable `fromValue` to the type referred by value `referValue`.
|
||||
//
|
||||
// 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 (c *impConverter) ConvertWithRefer(fromValue, referValue any, extraParams ...any) (any, error) {
|
||||
var referValueRf reflect.Value
|
||||
if v, ok := referValue.(reflect.Value); ok {
|
||||
referValueRf = v
|
||||
} else {
|
||||
referValueRf = reflect.ValueOf(referValue)
|
||||
}
|
||||
return c.doConvert(doConvertInput{
|
||||
FromValue: fromValue,
|
||||
ToTypeName: referValueRf.Type().String(),
|
||||
ReferValue: referValue,
|
||||
Extra: extraParams,
|
||||
})
|
||||
}
|
||||
|
||||
type doConvertInput struct {
|
||||
FromValue any // Value that is converted from.
|
||||
ToTypeName string // Target value type name in string.
|
||||
@ -389,7 +423,7 @@ func (c *impConverter) doConvert(in doConvertInput) (convertedValue any, err err
|
||||
|
||||
case reflect.Map:
|
||||
var targetValue = reflect.New(referReflectValue.Type()).Elem()
|
||||
if err = c.MapToMap(in.FromValue, targetValue); err == nil {
|
||||
if err = c.MapToMap(in.FromValue, targetValue, nil, MapOption{}); err == nil {
|
||||
in.alreadySetToReferValue = true
|
||||
}
|
||||
return targetValue.Interface(), nil
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"math"
|
||||
@ -44,7 +44,7 @@ func (c *impConverter) Int16(any any) (int16, error) {
|
||||
if v, ok := any.(int16); ok {
|
||||
return v, nil
|
||||
}
|
||||
v, err := defaultConverter.Int64(any)
|
||||
v, err := c.Int64(any)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -42,7 +42,7 @@ type MapOption struct {
|
||||
// priorityTagAndFieldName that will be detected, otherwise it detects the priorityTagAndFieldName in order of:
|
||||
// gconv, json, field name.
|
||||
func (c *impConverter) Map(value any, option MapOption) (map[string]any, error) {
|
||||
return c.doMapConvert(value, recursiveTypeAuto, false, option)
|
||||
return c.doMapConvert(value, RecursiveTypeAuto, false, option)
|
||||
}
|
||||
|
||||
// MapStrStr converts `value` to map[string]string.
|
||||
@ -77,7 +77,7 @@ func (c *impConverter) MapStrStr(value any, option MapOption) (map[string]string
|
||||
//
|
||||
// TODO completely implement the recursive converting for all types, especially the map.
|
||||
func (c *impConverter) doMapConvert(
|
||||
value any, recursive recursiveType, mustMapReturn bool, option MapOption,
|
||||
value any, recursive RecursiveType, mustMapReturn bool, option MapOption,
|
||||
) (map[string]any, error) {
|
||||
if value == nil {
|
||||
return nil, nil
|
||||
@ -91,7 +91,7 @@ func (c *impConverter) doMapConvert(
|
||||
newTags = gtag.StructTagPriority
|
||||
)
|
||||
if option.Deep {
|
||||
recursive = recursiveTypeTrue
|
||||
recursive = RecursiveTypeTrue
|
||||
}
|
||||
switch len(option.Tags) {
|
||||
case 0:
|
||||
@ -135,7 +135,7 @@ func (c *impConverter) doMapConvert(
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
RecursiveOption: recursive == RecursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
@ -208,7 +208,7 @@ func (c *impConverter) doMapConvert(
|
||||
dataMap[k] = v
|
||||
}
|
||||
case map[string]interface{}:
|
||||
if recursive == recursiveTypeTrue {
|
||||
if recursive == RecursiveTypeTrue {
|
||||
recursiveOption := option
|
||||
recursiveOption.Tags = newTags
|
||||
// A copy of current map.
|
||||
@ -218,7 +218,7 @@ func (c *impConverter) doMapConvert(
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
RecursiveOption: recursive == RecursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
@ -243,7 +243,7 @@ func (c *impConverter) doMapConvert(
|
||||
IsRoot: false,
|
||||
Value: v,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
RecursiveOption: recursive == RecursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
},
|
||||
)
|
||||
@ -290,7 +290,7 @@ func (c *impConverter) doMapConvert(
|
||||
case reflect.Slice, reflect.Array:
|
||||
length := reflectValue.Len()
|
||||
for i := 0; i < length; i += 2 {
|
||||
s, err := c.String(String(reflectValue.Index(i).Interface()))
|
||||
s, err := c.String(reflectValue.Index(i).Interface())
|
||||
if err != nil && option.BreakOnError {
|
||||
return nil, err
|
||||
}
|
||||
@ -308,7 +308,7 @@ func (c *impConverter) doMapConvert(
|
||||
IsRoot: true,
|
||||
Value: value,
|
||||
RecursiveType: recursive,
|
||||
RecursiveOption: recursive == recursiveTypeTrue,
|
||||
RecursiveOption: recursive == RecursiveTypeTrue,
|
||||
Option: recursiveOption,
|
||||
MustMapReturn: mustMapReturn,
|
||||
},
|
||||
@ -327,18 +327,10 @@ func (c *impConverter) doMapConvert(
|
||||
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 interface{} // Current operation value.
|
||||
RecursiveType recursiveType // The type from top function entry.
|
||||
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.
|
||||
@ -398,7 +390,7 @@ func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrSt
|
||||
IsRoot: false,
|
||||
Value: mapValue,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
@ -420,7 +412,7 @@ func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrSt
|
||||
IsRoot: false,
|
||||
Value: mapV,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
@ -550,7 +542,7 @@ func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrSt
|
||||
IsRoot: false,
|
||||
Value: rvInterface,
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
@ -573,7 +565,7 @@ func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrSt
|
||||
IsRoot: false,
|
||||
Value: rvAttrField.Index(arrayIndex).Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
@ -597,7 +589,7 @@ func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrSt
|
||||
IsRoot: false,
|
||||
Value: mapIter.Value().Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
},
|
||||
)
|
||||
@ -639,7 +631,7 @@ func (c *impConverter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrSt
|
||||
IsRoot: false,
|
||||
Value: reflectValue.Index(i).Interface(),
|
||||
RecursiveType: in.RecursiveType,
|
||||
RecursiveOption: in.RecursiveType == recursiveTypeTrue,
|
||||
RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
|
||||
Option: in.Option,
|
||||
})
|
||||
if err != nil && in.Option.BreakOnError {
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -23,15 +23,13 @@ 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 *impConverter) MapToMap(params any, pointer any, mapping ...map[string]string) (err error) {
|
||||
func (c *impConverter) MapToMap(
|
||||
params, pointer any, mapping map[string]string, option MapOption,
|
||||
) (err error) {
|
||||
var (
|
||||
paramsRv reflect.Value
|
||||
paramsKind reflect.Kind
|
||||
keyToAttributeNameMapping map[string]string
|
||||
paramsRv reflect.Value
|
||||
paramsKind reflect.Kind
|
||||
)
|
||||
if len(mapping) > 0 {
|
||||
keyToAttributeNameMapping = mapping[0]
|
||||
}
|
||||
if v, ok := params.(reflect.Value); ok {
|
||||
paramsRv = v
|
||||
} else {
|
||||
@ -43,7 +41,11 @@ func (c *impConverter) MapToMap(params any, pointer any, mapping ...map[string]s
|
||||
paramsKind = paramsRv.Kind()
|
||||
}
|
||||
if paramsKind != reflect.Map {
|
||||
return c.MapToMap(Map(params), pointer, mapping...)
|
||||
m, err := c.Map(params, option)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.MapToMap(m, pointer, mapping, option)
|
||||
}
|
||||
// Empty params map, no need continue.
|
||||
if paramsRv.Len() == 0 {
|
||||
@ -93,7 +95,7 @@ func (c *impConverter) MapToMap(params any, pointer any, mapping ...map[string]s
|
||||
switch pointerValueKind {
|
||||
case reflect.Map, reflect.Struct:
|
||||
if err = c.Struct(
|
||||
paramsRv.MapIndex(key).Interface(), mapValue, keyToAttributeNameMapping, "",
|
||||
paramsRv.MapIndex(key).Interface(), mapValue, mapping, "",
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -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 *impConverter) 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
|
||||
@ -103,13 +103,13 @@ func (c *impConverter) MapToMaps(params any, pointer any, paramKeyToAttrMap ...m
|
||||
var item reflect.Value
|
||||
if pointerElemType.Kind() == reflect.Ptr {
|
||||
item = reflect.New(pointerElemType.Elem())
|
||||
if err = c.MapToMap(paramsRv.Index(i).Interface(), item, paramKeyToAttrMap...); err != nil {
|
||||
if err = c.MapToMap(paramsRv.Index(i).Interface(), item, paramKeyToAttrMap, MapOption{}); err != nil {
|
||||
return err
|
||||
}
|
||||
pointerSlice.Index(i).Set(item)
|
||||
} else {
|
||||
item = reflect.New(pointerElemType)
|
||||
if err = c.MapToMap(paramsRv.Index(i).Interface(), item, paramKeyToAttrMap...); err != nil {
|
||||
if err = c.MapToMap(paramsRv.Index(i).Interface(), item, paramKeyToAttrMap, MapOption{}); err != nil {
|
||||
return err
|
||||
}
|
||||
pointerSlice.Index(i).Set(item.Elem())
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
func (c *impConverter) Rune(any any) (rune, error) {
|
||||
if v, ok := any.(rune); ok {
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -15,7 +15,12 @@ import (
|
||||
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
|
||||
)
|
||||
|
||||
func (c *impConverter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...map[string]string) (err error) {
|
||||
type ScanOption struct {
|
||||
ParamKeyToAttrMap map[string]string
|
||||
BreakOnError bool
|
||||
}
|
||||
|
||||
func (c *impConverter) Scan(srcValue any, dstPointer any, option ScanOption) (err error) {
|
||||
// Check if srcValue is nil, in which case no conversion is needed
|
||||
if srcValue == nil {
|
||||
return nil
|
||||
@ -79,12 +84,12 @@ func (c *impConverter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...m
|
||||
// Create a new value for the pointer dereference
|
||||
nextLevelPtr := reflect.New(dstPointerReflectValueElem.Type().Elem())
|
||||
// Recursively scan into the dereferenced pointer
|
||||
if err = Scan(srcValueReflectValue, nextLevelPtr, paramKeyToAttrMap...); err == nil {
|
||||
if err = c.Scan(srcValueReflectValue, nextLevelPtr, option); err == nil {
|
||||
dstPointerReflectValueElem.Set(nextLevelPtr)
|
||||
}
|
||||
return
|
||||
}
|
||||
return Scan(srcValueReflectValue, dstPointerReflectValueElem, paramKeyToAttrMap...)
|
||||
return c.Scan(srcValueReflectValue, dstPointerReflectValueElem, option)
|
||||
}
|
||||
|
||||
// Check if srcValue and dstPointer are the same type, in which case direct assignment can be performed
|
||||
@ -95,28 +100,43 @@ func (c *impConverter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...m
|
||||
// Handle different destination types
|
||||
switch dstPointerReflectValueElemKind {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
// Convert to int type
|
||||
dstPointerReflectValueElem.SetInt(Int64(srcValue))
|
||||
v, err := c.Int64(srcValue)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
dstPointerReflectValueElem.SetInt(v)
|
||||
return nil
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
// Convert to uint type
|
||||
dstPointerReflectValueElem.SetUint(Uint64(srcValue))
|
||||
v, err := c.Uint64(srcValue)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
dstPointerReflectValueElem.SetUint(v)
|
||||
return nil
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
// Convert to float type
|
||||
dstPointerReflectValueElem.SetFloat(Float64(srcValue))
|
||||
v, err := c.Float64(srcValue)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
dstPointerReflectValueElem.SetFloat(v)
|
||||
return nil
|
||||
|
||||
case reflect.String:
|
||||
// Convert to string type
|
||||
dstPointerReflectValueElem.SetString(String(srcValue))
|
||||
v, err := c.String(srcValue)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
dstPointerReflectValueElem.SetString(v)
|
||||
return nil
|
||||
|
||||
case reflect.Bool:
|
||||
// Convert to bool type
|
||||
dstPointerReflectValueElem.SetBool(Bool(srcValue))
|
||||
v, err := c.Bool(srcValue)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
dstPointerReflectValueElem.SetBool(v)
|
||||
return nil
|
||||
|
||||
case reflect.Slice:
|
||||
@ -132,7 +152,7 @@ func (c *impConverter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...m
|
||||
}
|
||||
// Special handling for struct or map slice elements
|
||||
if dstElemKind == reflect.Struct || dstElemKind == reflect.Map {
|
||||
return c.doScanForComplicatedTypes(srcValue, dstPointer, dstPointerReflectType, paramKeyToAttrMap...)
|
||||
return c.doScanForComplicatedTypes(srcValue, dstPointer, dstPointerReflectType, option)
|
||||
}
|
||||
// Handle basic type slice conversions
|
||||
var srcValueReflectValueKind = srcValueReflectValue.Kind()
|
||||
@ -145,29 +165,49 @@ func (c *impConverter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...m
|
||||
srcElem := srcValueReflectValue.Index(i).Interface()
|
||||
switch dstElemType.Kind() {
|
||||
case reflect.String:
|
||||
newSlice.Index(i).SetString(String(srcElem))
|
||||
v, err := c.String(srcElem)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
newSlice.Index(i).SetString(v)
|
||||
case reflect.Int:
|
||||
newSlice.Index(i).SetInt(Int64(srcElem))
|
||||
v, err := c.Int64(srcElem)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
newSlice.Index(i).SetInt(v)
|
||||
case reflect.Int64:
|
||||
newSlice.Index(i).SetInt(Int64(srcElem))
|
||||
v, err := c.Int64(srcElem)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
newSlice.Index(i).SetInt(v)
|
||||
case reflect.Float64:
|
||||
newSlice.Index(i).SetFloat(Float64(srcElem))
|
||||
v, err := c.Float64(srcElem)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
newSlice.Index(i).SetFloat(v)
|
||||
case reflect.Bool:
|
||||
newSlice.Index(i).SetBool(Bool(srcElem))
|
||||
v, err := c.Bool(srcElem)
|
||||
if err != nil && option.BreakOnError {
|
||||
return err
|
||||
}
|
||||
newSlice.Index(i).SetBool(v)
|
||||
default:
|
||||
return Scan(
|
||||
srcElem, newSlice.Index(i).Addr().Interface(), paramKeyToAttrMap...,
|
||||
return c.Scan(
|
||||
srcElem, newSlice.Index(i).Addr().Interface(), option,
|
||||
)
|
||||
}
|
||||
}
|
||||
dstPointerReflectValueElem.Set(newSlice)
|
||||
return nil
|
||||
}
|
||||
return c.doScanForComplicatedTypes(srcValue, dstPointer, dstPointerReflectType, paramKeyToAttrMap...)
|
||||
return c.doScanForComplicatedTypes(srcValue, dstPointer, dstPointerReflectType, option)
|
||||
|
||||
default:
|
||||
// Handle complex types (structs, maps, etc.)
|
||||
return c.doScanForComplicatedTypes(srcValue, dstPointer, dstPointerReflectType, paramKeyToAttrMap...)
|
||||
return c.doScanForComplicatedTypes(srcValue, dstPointer, dstPointerReflectType, option)
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +225,7 @@ func (c *impConverter) Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...m
|
||||
func (c *impConverter) doScanForComplicatedTypes(
|
||||
srcValue, dstPointer any,
|
||||
dstPointerReflectType reflect.Type,
|
||||
paramKeyToAttrMap ...map[string]string,
|
||||
option ScanOption,
|
||||
) error {
|
||||
// Try JSON conversion first
|
||||
ok, err := c.doConvertWithJsonCheck(srcValue, dstPointer)
|
||||
@ -200,17 +240,13 @@ func (c *impConverter) doScanForComplicatedTypes(
|
||||
var (
|
||||
dstPointerReflectTypeElem = dstPointerReflectType.Elem()
|
||||
dstPointerReflectTypeElemKind = dstPointerReflectTypeElem.Kind()
|
||||
keyToAttributeNameMapping map[string]string
|
||||
keyToAttributeNameMapping = option.ParamKeyToAttrMap
|
||||
)
|
||||
if len(paramKeyToAttrMap) > 0 {
|
||||
keyToAttributeNameMapping = paramKeyToAttrMap[0]
|
||||
}
|
||||
|
||||
// Handle different destination types
|
||||
switch dstPointerReflectTypeElemKind {
|
||||
case reflect.Map:
|
||||
// Convert map to map
|
||||
return c.MapToMap(srcValue, dstPointer, paramKeyToAttrMap...)
|
||||
return c.MapToMap(srcValue, dstPointer, keyToAttributeNameMapping, MapOption{})
|
||||
|
||||
case reflect.Array, reflect.Slice:
|
||||
var (
|
||||
@ -224,7 +260,7 @@ func (c *impConverter) doScanForComplicatedTypes(
|
||||
}
|
||||
if sliceElemKind == reflect.Map {
|
||||
// Convert to slice of maps
|
||||
return c.MapToMaps(srcValue, dstPointer, paramKeyToAttrMap...)
|
||||
return c.MapToMaps(srcValue, dstPointer, keyToAttributeNameMapping)
|
||||
}
|
||||
// Convert to slice of structs
|
||||
return c.Structs(srcValue, dstPointer, keyToAttributeNameMapping, "")
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import "github.com/gogf/gf/v2/internal/json"
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -38,7 +38,11 @@ func (c *impConverter) SliceStr(any interface{}, option SliceOption) ([]string,
|
||||
case []int8:
|
||||
array = make([]string, len(value))
|
||||
for k, v := range value {
|
||||
array[k] = String(v)
|
||||
s, err = c.String(v)
|
||||
if err != nil && option.BreakOnError {
|
||||
return nil, err
|
||||
}
|
||||
array[k] = s
|
||||
}
|
||||
case []int16:
|
||||
array = make([]string, len(value))
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -133,7 +133,7 @@ func (c *impConverter) Struct(
|
||||
if !ok {
|
||||
// paramsMap is the map[string]any type variable for params.
|
||||
// DO NOT use MapDeep here.
|
||||
paramsMap, err = c.doMapConvert(paramsInterface, recursiveTypeAuto, true, MapOption{})
|
||||
paramsMap, err = c.doMapConvert(paramsInterface, RecursiveTypeAuto, true, MapOption{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -470,7 +470,7 @@ func (c *impConverter) bindVarToReflectValue(
|
||||
// Converting using reflection by kind.
|
||||
switch kind {
|
||||
case reflect.Map:
|
||||
return c.MapToMap(value, structFieldValue, paramKeyToAttrMap)
|
||||
return c.MapToMap(value, structFieldValue, paramKeyToAttrMap, MapOption{})
|
||||
|
||||
case reflect.Struct:
|
||||
// Recursively converting for struct attribute.
|
||||
@ -512,13 +512,16 @@ func (c *impConverter) bindVarToReflectValue(
|
||||
}
|
||||
}
|
||||
if !converted {
|
||||
c.doConvertWithReflectValueSet(
|
||||
err = c.doConvertWithReflectValueSet(
|
||||
elem, doConvertInput{
|
||||
FromValue: reflectValue.Index(i).Interface(),
|
||||
ToTypeName: elemTypeName,
|
||||
ReferValue: elem,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
// Before it sets the `elem` to array, do pointer converting if necessary.
|
||||
@ -566,13 +569,16 @@ func (c *impConverter) bindVarToReflectValue(
|
||||
}
|
||||
}
|
||||
if !converted {
|
||||
c.doConvertWithReflectValueSet(
|
||||
err = c.doConvertWithReflectValueSet(
|
||||
elem, doConvertInput{
|
||||
FromValue: value,
|
||||
ToTypeName: elemTypeName,
|
||||
ReferValue: elem,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
// Before it sets the `elem` to array, do pointer converting if necessary.
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@ -62,7 +62,10 @@ func (c *impConverter) Structs(
|
||||
paramsList[i] = paramsRv.Index(i).Interface()
|
||||
}
|
||||
default:
|
||||
var paramsMaps = Maps(params)
|
||||
paramsMaps, err := c.SliceMap(params, SliceOption{}, MapOption{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
paramsList = make([]any, len(paramsMaps))
|
||||
for i := 0; i < len(paramsMaps); i++ {
|
||||
paramsList[i] = paramsMaps[i]
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"time"
|
||||
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gconv
|
||||
package converter
|
||||
|
||||
import (
|
||||
"math"
|
||||
Reference in New Issue
Block a user