From 1c1558b1f71aa04626252295d2e581be895c4331 Mon Sep 17 00:00:00 2001 From: John Guo Date: Sun, 2 Mar 2025 23:21:59 +0800 Subject: [PATCH] up --- util/gconv/gconv.go | 19 ++-- util/gconv/gconv_convert.go | 26 +---- util/gconv/gconv_map.go | 15 +-- util/gconv/gconv_scan.go | 6 +- .../converter/converter.go} | 20 +++- .../converter/converter_bool.go} | 2 +- .../converter/converter_builtin.go} | 2 +- .../converter/converter_bytes.go} | 2 +- .../converter/converter_convert.go} | 38 ++++++- .../converter/converter_float.go} | 2 +- .../converter/converter_int.go} | 4 +- .../converter/converter_map.go} | 42 +++----- .../converter/converter_maptomap.go} | 22 ++-- .../converter/converter_maptomaps.go} | 8 +- .../converter/converter_rune.go} | 2 +- .../converter/converter_scan.go} | 100 ++++++++++++------ .../converter/converter_slice_any.go} | 2 +- .../converter/converter_slice_float.go} | 2 +- .../converter/converter_slice_int.go} | 2 +- .../converter/converter_slice_map.go} | 2 +- .../converter/converter_slice_str.go} | 8 +- .../converter/converter_slice_uint.go} | 2 +- .../converter/converter_string.go} | 2 +- .../converter/converter_struct.go} | 16 ++- .../converter/converter_structs.go} | 7 +- .../converter/converter_time.go} | 2 +- .../converter/converter_uint.go} | 2 +- 27 files changed, 215 insertions(+), 142 deletions(-) rename util/gconv/{gconv_converter.go => internal/converter/converter.go} (94%) rename util/gconv/{gconv_converter_bool.go => internal/converter/converter_bool.go} (99%) rename util/gconv/{gconv_converter_builtin.go => internal/converter/converter_builtin.go} (99%) rename util/gconv/{gconv_converter_bytes.go => internal/converter/converter_bytes.go} (98%) rename util/gconv/{gconv_converter_convert.go => internal/converter/converter_convert.go} (90%) rename util/gconv/{gconv_converter_float.go => internal/converter/converter_float.go} (99%) rename util/gconv/{gconv_converter_int.go => internal/converter/converter_int.go} (98%) rename util/gconv/{gconv_converter_map.go => internal/converter/converter_map.go} (94%) rename util/gconv/{gconv_converter_maptomap.go => internal/converter/converter_maptomap.go} (88%) rename util/gconv/{gconv_converter_maptomaps.go => internal/converter/converter_maptomaps.go} (95%) rename util/gconv/{gconv_converter_rune.go => internal/converter/converter_rune.go} (97%) rename util/gconv/{gconv_converter_scan.go => internal/converter/converter_scan.go} (82%) rename util/gconv/{gconv_converter_slice_any.go => internal/converter/converter_slice_any.go} (99%) rename util/gconv/{gconv_converter_slice_float.go => internal/converter/converter_slice_float.go} (99%) rename util/gconv/{gconv_converter_slice_int.go => internal/converter/converter_slice_int.go} (99%) rename util/gconv/{gconv_converter_slice_map.go => internal/converter/converter_slice_map.go} (98%) rename util/gconv/{gconv_converter_slice_str.go => internal/converter/converter_slice_str.go} (97%) rename util/gconv/{gconv_converter_slice_uint.go => internal/converter/converter_slice_uint.go} (99%) rename util/gconv/{gconv_converter_string.go => internal/converter/converter_string.go} (99%) rename util/gconv/{gconv_converter_struct.go => internal/converter/converter_struct.go} (98%) rename util/gconv/{gconv_converter_structs.go => internal/converter/converter_structs.go} (96%) rename util/gconv/{gconv_converter_time.go => internal/converter/converter_time.go} (99%) rename util/gconv/{gconv_converter_uint.go => internal/converter/converter_uint.go} (99%) diff --git a/util/gconv/gconv.go b/util/gconv/gconv.go index be49d479a..5ec146f2a 100644 --- a/util/gconv/gconv.go +++ b/util/gconv/gconv.go @@ -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. diff --git a/util/gconv/gconv_convert.go b/util/gconv/gconv_convert.go index 53db02f1c..134651aca 100644 --- a/util/gconv/gconv_convert.go +++ b/util/gconv/gconv_convert.go @@ -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 } diff --git a/util/gconv/gconv_map.go b/util/gconv/gconv_map.go index 9c49f9e31..1aede25b5 100644 --- a/util/gconv/gconv_map.go +++ b/util/gconv/gconv_map.go @@ -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 +} diff --git a/util/gconv/gconv_scan.go b/util/gconv/gconv_scan.go index 806438668..8edbc0aca 100644 --- a/util/gconv/gconv_scan.go +++ b/util/gconv/gconv_scan.go @@ -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) } diff --git a/util/gconv/gconv_converter.go b/util/gconv/internal/converter/converter.go similarity index 94% rename from util/gconv/gconv_converter.go rename to util/gconv/internal/converter/converter.go index 86157c9c0..a9e726952 100644 --- a/util/gconv/gconv_converter.go +++ b/util/gconv/internal/converter/converter.go @@ -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)) diff --git a/util/gconv/gconv_converter_bool.go b/util/gconv/internal/converter/converter_bool.go similarity index 99% rename from util/gconv/gconv_converter_bool.go rename to util/gconv/internal/converter/converter_bool.go index 5b080d9df..d9e88c41e 100644 --- a/util/gconv/gconv_converter_bool.go +++ b/util/gconv/internal/converter/converter_bool.go @@ -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" diff --git a/util/gconv/gconv_converter_builtin.go b/util/gconv/internal/converter/converter_builtin.go similarity index 99% rename from util/gconv/gconv_converter_builtin.go rename to util/gconv/internal/converter/converter_builtin.go index 2d8a3aee1..b8a8e0e47 100644 --- a/util/gconv/gconv_converter_builtin.go +++ b/util/gconv/internal/converter/converter_builtin.go @@ -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" diff --git a/util/gconv/gconv_converter_bytes.go b/util/gconv/internal/converter/converter_bytes.go similarity index 98% rename from util/gconv/gconv_converter_bytes.go rename to util/gconv/internal/converter/converter_bytes.go index 437f90780..dfec4eef0 100644 --- a/util/gconv/gconv_converter_bytes.go +++ b/util/gconv/internal/converter/converter_bytes.go @@ -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" diff --git a/util/gconv/gconv_converter_convert.go b/util/gconv/internal/converter/converter_convert.go similarity index 90% rename from util/gconv/gconv_converter_convert.go rename to util/gconv/internal/converter/converter_convert.go index f6d30ec84..68195d0f6 100644 --- a/util/gconv/gconv_converter_convert.go +++ b/util/gconv/internal/converter/converter_convert.go @@ -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 diff --git a/util/gconv/gconv_converter_float.go b/util/gconv/internal/converter/converter_float.go similarity index 99% rename from util/gconv/gconv_converter_float.go rename to util/gconv/internal/converter/converter_float.go index d9e5520d6..2e9968120 100644 --- a/util/gconv/gconv_converter_float.go +++ b/util/gconv/internal/converter/converter_float.go @@ -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" diff --git a/util/gconv/gconv_converter_int.go b/util/gconv/internal/converter/converter_int.go similarity index 98% rename from util/gconv/gconv_converter_int.go rename to util/gconv/internal/converter/converter_int.go index fb742471c..b3999734a 100644 --- a/util/gconv/gconv_converter_int.go +++ b/util/gconv/internal/converter/converter_int.go @@ -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 } diff --git a/util/gconv/gconv_converter_map.go b/util/gconv/internal/converter/converter_map.go similarity index 94% rename from util/gconv/gconv_converter_map.go rename to util/gconv/internal/converter/converter_map.go index 02a08380e..e0dfe0cc3 100644 --- a/util/gconv/gconv_converter_map.go +++ b/util/gconv/internal/converter/converter_map.go @@ -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 { diff --git a/util/gconv/gconv_converter_maptomap.go b/util/gconv/internal/converter/converter_maptomap.go similarity index 88% rename from util/gconv/gconv_converter_maptomap.go rename to util/gconv/internal/converter/converter_maptomap.go index 5026ce223..51a8be2cf 100644 --- a/util/gconv/gconv_converter_maptomap.go +++ b/util/gconv/internal/converter/converter_maptomap.go @@ -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 } diff --git a/util/gconv/gconv_converter_maptomaps.go b/util/gconv/internal/converter/converter_maptomaps.go similarity index 95% rename from util/gconv/gconv_converter_maptomaps.go rename to util/gconv/internal/converter/converter_maptomaps.go index 1c5c266a7..3a842585f 100644 --- a/util/gconv/gconv_converter_maptomaps.go +++ b/util/gconv/internal/converter/converter_maptomaps.go @@ -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()) diff --git a/util/gconv/gconv_converter_rune.go b/util/gconv/internal/converter/converter_rune.go similarity index 97% rename from util/gconv/gconv_converter_rune.go rename to util/gconv/internal/converter/converter_rune.go index 0a6c5fdca..301687d02 100644 --- a/util/gconv/gconv_converter_rune.go +++ b/util/gconv/internal/converter/converter_rune.go @@ -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 { diff --git a/util/gconv/gconv_converter_scan.go b/util/gconv/internal/converter/converter_scan.go similarity index 82% rename from util/gconv/gconv_converter_scan.go rename to util/gconv/internal/converter/converter_scan.go index 344e18f25..15b207f03 100644 --- a/util/gconv/gconv_converter_scan.go +++ b/util/gconv/internal/converter/converter_scan.go @@ -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, "") diff --git a/util/gconv/gconv_converter_slice_any.go b/util/gconv/internal/converter/converter_slice_any.go similarity index 99% rename from util/gconv/gconv_converter_slice_any.go rename to util/gconv/internal/converter/converter_slice_any.go index 936805340..c020d5ad6 100644 --- a/util/gconv/gconv_converter_slice_any.go +++ b/util/gconv/internal/converter/converter_slice_any.go @@ -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" diff --git a/util/gconv/gconv_converter_slice_float.go b/util/gconv/internal/converter/converter_slice_float.go similarity index 99% rename from util/gconv/gconv_converter_slice_float.go rename to util/gconv/internal/converter/converter_slice_float.go index 0bb93fd11..85f1e0071 100644 --- a/util/gconv/gconv_converter_slice_float.go +++ b/util/gconv/internal/converter/converter_slice_float.go @@ -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" diff --git a/util/gconv/gconv_converter_slice_int.go b/util/gconv/internal/converter/converter_slice_int.go similarity index 99% rename from util/gconv/gconv_converter_slice_int.go rename to util/gconv/internal/converter/converter_slice_int.go index 437e36b55..1c05a5327 100644 --- a/util/gconv/gconv_converter_slice_int.go +++ b/util/gconv/internal/converter/converter_slice_int.go @@ -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" diff --git a/util/gconv/gconv_converter_slice_map.go b/util/gconv/internal/converter/converter_slice_map.go similarity index 98% rename from util/gconv/gconv_converter_slice_map.go rename to util/gconv/internal/converter/converter_slice_map.go index 0bd5ecdfd..6e040ea06 100644 --- a/util/gconv/gconv_converter_slice_map.go +++ b/util/gconv/internal/converter/converter_slice_map.go @@ -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" diff --git a/util/gconv/gconv_converter_slice_str.go b/util/gconv/internal/converter/converter_slice_str.go similarity index 97% rename from util/gconv/gconv_converter_slice_str.go rename to util/gconv/internal/converter/converter_slice_str.go index ff8734e7d..a62658dda 100644 --- a/util/gconv/gconv_converter_slice_str.go +++ b/util/gconv/internal/converter/converter_slice_str.go @@ -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)) diff --git a/util/gconv/gconv_converter_slice_uint.go b/util/gconv/internal/converter/converter_slice_uint.go similarity index 99% rename from util/gconv/gconv_converter_slice_uint.go rename to util/gconv/internal/converter/converter_slice_uint.go index b66e0aca2..9e44b7428 100644 --- a/util/gconv/gconv_converter_slice_uint.go +++ b/util/gconv/internal/converter/converter_slice_uint.go @@ -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" diff --git a/util/gconv/gconv_converter_string.go b/util/gconv/internal/converter/converter_string.go similarity index 99% rename from util/gconv/gconv_converter_string.go rename to util/gconv/internal/converter/converter_string.go index dd38ac119..e3415abd7 100644 --- a/util/gconv/gconv_converter_string.go +++ b/util/gconv/internal/converter/converter_string.go @@ -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" diff --git a/util/gconv/gconv_converter_struct.go b/util/gconv/internal/converter/converter_struct.go similarity index 98% rename from util/gconv/gconv_converter_struct.go rename to util/gconv/internal/converter/converter_struct.go index bd38209d8..5b6fdb94e 100644 --- a/util/gconv/gconv_converter_struct.go +++ b/util/gconv/internal/converter/converter_struct.go @@ -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. diff --git a/util/gconv/gconv_converter_structs.go b/util/gconv/internal/converter/converter_structs.go similarity index 96% rename from util/gconv/gconv_converter_structs.go rename to util/gconv/internal/converter/converter_structs.go index dc722385d..5f003d7ef 100644 --- a/util/gconv/gconv_converter_structs.go +++ b/util/gconv/internal/converter/converter_structs.go @@ -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] diff --git a/util/gconv/gconv_converter_time.go b/util/gconv/internal/converter/converter_time.go similarity index 99% rename from util/gconv/gconv_converter_time.go rename to util/gconv/internal/converter/converter_time.go index 974daf451..4f5b416ba 100644 --- a/util/gconv/gconv_converter_time.go +++ b/util/gconv/internal/converter/converter_time.go @@ -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" diff --git a/util/gconv/gconv_converter_uint.go b/util/gconv/internal/converter/converter_uint.go similarity index 99% rename from util/gconv/gconv_converter_uint.go rename to util/gconv/internal/converter/converter_uint.go index 90691feed..eb1b91241 100644 --- a/util/gconv/gconv_converter_uint.go +++ b/util/gconv/internal/converter/converter_uint.go @@ -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"