Skip to content

Commit

Permalink
1.文件名优化
Browse files Browse the repository at this point in the history
2.存储接口类型的转换由map改为slice,以保证稳定性
3.全局变量defaultConfig改为方法调用DefaultConvertConfig()
  • Loading branch information
wln32 committed Jan 14, 2025
1 parent 4026da1 commit 5caada1
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 26 deletions.
4 changes: 4 additions & 0 deletions util/gconv/gconv_convert_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ type ConvertConfig = structcache.ConvertConfig

var defaultConfig = structcache.GetDefaultConfig()

func DefaultConvertConfig() *ConvertConfig {
return defaultConfig
}

func NewConvertConfig(name string) *ConvertConfig {
return structcache.NewConvertConfig(name)
}
Expand Down
2 changes: 1 addition & 1 deletion util/gconv/gconv_maptomap.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func doMapToMap(params interface{}, pointer interface{}, mapping ...map[string]s
switch pointerValueKind {
case reflect.Map, reflect.Struct:
if err = doStruct(
paramsRv.MapIndex(key).Interface(), mapValue, keyToAttributeNameMapping, "", defaultConfig,
paramsRv.MapIndex(key).Interface(), mapValue, keyToAttributeNameMapping, "", DefaultConvertConfig(),
); err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion util/gconv/gconv_scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
//
// TODO change `paramKeyToAttrMap` to `ScanOption` to be more scalable; add `DeepCopy` option for `ScanOption`.
func Scan(srcValue interface{}, dstPointer interface{}, paramKeyToAttrMap ...map[string]string) (err error) {
return scan(defaultConfig, srcValue, dstPointer, paramKeyToAttrMap...)
return scan(DefaultConvertConfig(), srcValue, dstPointer, paramKeyToAttrMap...)
}

func scan(config *ConvertConfig, srcValue interface{}, dstPointer interface{}, paramKeyToAttrMap ...map[string]string) (err error) {
Expand Down
8 changes: 4 additions & 4 deletions util/gconv/gconv_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func Struct(params interface{}, pointer interface{}, paramKeyToAttrMap ...map[st
// specified priorityTagAndFieldName for `params` key-value items to struct attribute names mapping.
// The parameter `priorityTag` supports multiple priorityTagAndFieldName that can be joined with char ','.
func StructTag(params interface{}, pointer interface{}, priorityTag string) (err error) {
return doStruct(params, pointer, nil, priorityTag, defaultConfig)
return doStruct(params, pointer, nil, priorityTag, DefaultConvertConfig())
}

// doStruct is the core internal converting function for any data to struct.
Expand Down Expand Up @@ -491,7 +491,7 @@ func bindVarToReflectValue(

case reflect.Struct:
// Recursively converting for struct attribute.
if err = doStruct(value, structFieldValue, nil, "", defaultConfig); err != nil {
if err = doStruct(value, structFieldValue, nil, "", DefaultConvertConfig()); err != nil {
// Note there's reflect conversion mechanism here.
structFieldValue.Set(reflect.ValueOf(value).Convert(structFieldValue.Type()))
}
Expand Down Expand Up @@ -524,7 +524,7 @@ func bindVarToReflectValue(
elem = reflect.New(elemType).Elem()
}
if elem.Kind() == reflect.Struct {
if err = doStruct(reflectValue.Index(i).Interface(), elem, nil, "", defaultConfig); err == nil {
if err = doStruct(reflectValue.Index(i).Interface(), elem, nil, "", DefaultConvertConfig()); err == nil {
converted = true
}
}
Expand Down Expand Up @@ -574,7 +574,7 @@ func bindVarToReflectValue(
elem = reflect.New(elemType).Elem()
}
if elem.Kind() == reflect.Struct {
if err = doStruct(value, elem, nil, "", defaultConfig); err == nil {
if err = doStruct(value, elem, nil, "", DefaultConvertConfig()); err == nil {
converted = true
}
}
Expand Down
2 changes: 1 addition & 1 deletion util/gconv/gconv_structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func SliceStruct(params interface{}, pointer interface{}, mapping ...map[string]
// specified priorityTagAndFieldName for `params` key-value items to struct attribute names mapping.
// The parameter `priorityTag` supports multiple priorityTagAndFieldName that can be joined with char ','.
func StructsTag(params interface{}, pointer interface{}, priorityTag string) (err error) {
return doStructs(params, pointer, nil, priorityTag, defaultConfig)
return doStructs(params, pointer, nil, priorityTag, DefaultConvertConfig())
}

// doStructs converts any slice to given struct slice.
Expand Down
2 changes: 1 addition & 1 deletion util/gconv/gconv_z_bench_struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func Benchmark_Struct_Basic(b *testing.B) {

func Benchmark_doStruct_Fields8_Basic_MapToStruct(b *testing.B) {
for i := 0; i < b.N; i++ {
doStruct(structMapFields8, structPointer8, map[string]string{}, "", defaultConfig)
doStruct(structMapFields8, structPointer8, map[string]string{}, "", DefaultConvertConfig())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,23 @@ import (

type convertFn = func(from any, to reflect.Value) error

type interfaceTypeConvert struct {
typ reflect.Type
fn convertFn
}

type ConvertConfig struct {
name string
parseConvertFuncs map[reflect.Type]convertFn
interfaceConvertFuncs map[reflect.Type]convertFn
interfaceConvertFuncs []interfaceTypeConvert
// map[reflect.Type]*CachedStructInfo
cachedStructsInfoMap sync.Map
}

func NewConvertConfig(name string) *ConvertConfig {
return &ConvertConfig{
name: name,
parseConvertFuncs: make(map[reflect.Type]convertFn),
interfaceConvertFuncs: make(map[reflect.Type]convertFn),
name: name,
parseConvertFuncs: make(map[reflect.Type]convertFn),
}
}

Expand Down Expand Up @@ -55,13 +59,18 @@ func (cf *ConvertConfig) RegisterInterfaceTypeConvertFunc(typ reflect.Type, f co
if typ.NumMethod() == 0 {
panic("Please register using the [RegisterTypeConvertFunc] function")
}
cf.interfaceConvertFuncs[typ] = f
cf.interfaceConvertFuncs = append(cf.interfaceConvertFuncs,
interfaceTypeConvert{
typ: typ,
fn: f,
},
)
}

func (cf *ConvertConfig) checkTypeImplInterface(typ reflect.Type) convertFn {
for inter, fn := range cf.interfaceConvertFuncs {
if typ.Implements(inter) {
return fn
for _, inter := range cf.interfaceConvertFuncs {
if typ.Implements(inter.typ) {
return inter.fn
}
}
return nil
Expand Down Expand Up @@ -105,9 +114,6 @@ func (cf *ConvertConfig) getTypeConvertFunc(typ reflect.Type) (fn convertFn) {
// TODO is value type typ.Addr
typ = reflect.PointerTo(typ)
fn = cf.checkTypeImplInterface(typ)
if fn != nil {
return ptrConvertFunc(ptr, fn)
}
}
if fn != nil {
fn = ptrConvertFunc(ptr, fn)
Expand All @@ -116,16 +122,14 @@ func (cf *ConvertConfig) getTypeConvertFunc(typ reflect.Type) (fn convertFn) {
}

func ptrConvertFunc(ptr int, fn convertFn) convertFn {
if ptr > 0 {
return ptrConvertFunc(ptr-1, getPtrConvertFunc(fn))
for i := 0; i < ptr; i++ {
fn = getPtrConvertFunc(fn)
}
return fn
}

func getPtrConvertFunc(
convertFunc convertFn,
) convertFn {
if convertFunc == nil {
func getPtrConvertFunc(fn convertFn) convertFn {
if fn == nil {
panic("The conversion function cannot be empty")
}
return func(from any, to reflect.Value) error {
Expand All @@ -134,6 +138,6 @@ func getPtrConvertFunc(
}
// from = nil
// to = nil ??
return convertFunc(from, to.Elem())
return fn(from, to.Elem())
}
}

0 comments on commit 5caada1

Please sign in to comment.