From 86e763c60809b7641ecfba662ced0fb407b7b388 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 22:36:10 +0000 Subject: [PATCH] Bump github.com/jinzhu/copier from 0.3.5 to 0.4.0 Bumps [github.com/jinzhu/copier](https://github.com/jinzhu/copier) from 0.3.5 to 0.4.0. - [Commits](https://github.com/jinzhu/copier/compare/v0.3.5...v0.4.0) --- updated-dependencies: - dependency-name: github.com/jinzhu/copier dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +- vendor/github.com/jinzhu/copier/.gitignore | 2 + vendor/github.com/jinzhu/copier/README.md | 10 +- vendor/github.com/jinzhu/copier/copier.go | 405 ++++++++++++++------- vendor/github.com/jinzhu/copier/errors.go | 9 +- vendor/modules.txt | 2 +- 7 files changed, 284 insertions(+), 150 deletions(-) create mode 100644 vendor/github.com/jinzhu/copier/.gitignore diff --git a/go.mod b/go.mod index 2a05bee..d63bae4 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/go-test/deep v1.1.0 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.0 - github.com/jinzhu/copier v0.3.5 + github.com/jinzhu/copier v0.4.0 github.com/lfritz/env v1.0.0 github.com/markcheno/go-talib v0.0.0-20190307022042-cd53a9264d70 github.com/piquette/finance-go v1.0.0 diff --git a/go.sum b/go.sum index 61c16c3..d6cc11c 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= -github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= diff --git a/vendor/github.com/jinzhu/copier/.gitignore b/vendor/github.com/jinzhu/copier/.gitignore new file mode 100644 index 0000000..6d742b3 --- /dev/null +++ b/vendor/github.com/jinzhu/copier/.gitignore @@ -0,0 +1,2 @@ +.idea/ +ttt/ diff --git a/vendor/github.com/jinzhu/copier/README.md b/vendor/github.com/jinzhu/copier/README.md index ec04b4b..079dc57 100644 --- a/vendor/github.com/jinzhu/copier/README.md +++ b/vendor/github.com/jinzhu/copier/README.md @@ -30,7 +30,7 @@ type User struct { Name string Role string Age int32 - EmployeCode int64 `copier:"EmployeNum"` // specify field name + EmployeeCode int64 `copier:"EmployeeNum"` // specify field name // Explicitly ignored in the destination struct. Salary int @@ -53,7 +53,7 @@ type Employee struct { Salary int `copier:"-"` DoubleAge int32 - EmployeId int64 `copier:"EmployeNum"` // specify field name + EmployeeId int64 `copier:"EmployeeNum"` // specify field name SuperRole string } @@ -86,7 +86,7 @@ func main() { fmt.Printf("%#v \n", employees) // []Employee{ - // {Name: "Jinzhu", Age: 18, Salary:0, DoubleAge: 36, EmployeId: 0, SuperRole: "Super Admin"} + // {Name: "Jinzhu", Age: 18, Salary:0, DoubleAge: 36, EmployeeId: 0, SuperRole: "Super Admin"} // } // Copy slice to slice @@ -95,8 +95,8 @@ func main() { fmt.Printf("%#v \n", employees) // []Employee{ - // {Name: "Jinzhu", Age: 18, Salary:0, DoubleAge: 36, EmployeId: 0, SuperRole: "Super Admin"}, - // {Name: "jinzhu 2", Age: 30, Salary:0, DoubleAge: 60, EmployeId: 0, SuperRole: "Super Dev"}, + // {Name: "Jinzhu", Age: 18, Salary:0, DoubleAge: 36, EmployeeId: 0, SuperRole: "Super Admin"}, + // {Name: "jinzhu 2", Age: 30, Salary:0, DoubleAge: 60, EmployeeId: 0, SuperRole: "Super Dev"}, // } // Copy map to map diff --git a/vendor/github.com/jinzhu/copier/copier.go b/vendor/github.com/jinzhu/copier/copier.go index 6dc9600..43a14f1 100644 --- a/vendor/github.com/jinzhu/copier/copier.go +++ b/vendor/github.com/jinzhu/copier/copier.go @@ -3,10 +3,10 @@ package copier import ( "database/sql" "database/sql/driver" - "errors" "fmt" "reflect" "strings" + "sync" "unicode" ) @@ -37,15 +37,35 @@ const ( type Option struct { // setting this value to true will ignore copying zero values of all the fields, including bools, as well as a // struct having all it's fields set to their zero values respectively (see IsZero() in reflect/value.go) - IgnoreEmpty bool - DeepCopy bool - Converters []TypeConverter + IgnoreEmpty bool + CaseSensitive bool + DeepCopy bool + Converters []TypeConverter + // Custom field name mappings to copy values with different names in `fromValue` and `toValue` types. + // Examples can be found in `copier_field_name_mapping_test.go`. + FieldNameMapping []FieldNameMapping +} + +func (opt Option) converters() map[converterPair]TypeConverter { + var converters = map[converterPair]TypeConverter{} + + // save converters into map for faster lookup + for i := range opt.Converters { + pair := converterPair{ + SrcType: reflect.TypeOf(opt.Converters[i].SrcType), + DstType: reflect.TypeOf(opt.Converters[i].DstType), + } + + converters[pair] = opt.Converters[i] + } + + return converters } type TypeConverter struct { SrcType interface{} DstType interface{} - Fn func(src interface{}) (interface{}, error) + Fn func(src interface{}) (dst interface{}, err error) } type converterPair struct { @@ -53,6 +73,27 @@ type converterPair struct { DstType reflect.Type } +func (opt Option) fieldNameMapping() map[converterPair]FieldNameMapping { + var mapping = map[converterPair]FieldNameMapping{} + + for i := range opt.FieldNameMapping { + pair := converterPair{ + SrcType: reflect.TypeOf(opt.FieldNameMapping[i].SrcType), + DstType: reflect.TypeOf(opt.FieldNameMapping[i].DstType), + } + + mapping[pair] = opt.FieldNameMapping[i] + } + + return mapping +} + +type FieldNameMapping struct { + SrcType interface{} + DstType interface{} + Mapping map[string]string +} + // Tag Flags type flags struct { BitFlags map[string]uint8 @@ -82,23 +123,10 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) amount = 1 from = indirect(reflect.ValueOf(fromValue)) to = indirect(reflect.ValueOf(toValue)) - converters map[converterPair]TypeConverter + converters = opt.converters() + mappings = opt.fieldNameMapping() ) - // save convertes into map for faster lookup - for i := range opt.Converters { - if converters == nil { - converters = make(map[converterPair]TypeConverter) - } - - pair := converterPair{ - SrcType: reflect.TypeOf(opt.Converters[i].SrcType), - DstType: reflect.TypeOf(opt.Converters[i].DstType), - } - - converters[pair] = opt.Converters[i] - } - if !to.CanAddr() { return ErrInvalidCopyDestination } @@ -147,7 +175,11 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) for _, k := range from.MapKeys() { toKey := indirect(reflect.New(toType.Key())) - if !set(toKey, k, opt.DeepCopy, converters) { + isSet, err := set(toKey, k, opt.DeepCopy, converters) + if err != nil { + return err + } + if !isSet { return fmt.Errorf("%w map, old key: %v, new key: %v", ErrNotSupported, k.Type(), toType.Key()) } @@ -156,7 +188,11 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) elemType, _ = indirectType(elemType) } toValue := indirect(reflect.New(elemType)) - if !set(toValue, from.MapIndex(k), opt.DeepCopy, converters) { + isSet, err = set(toValue, from.MapIndex(k), opt.DeepCopy, converters) + if err != nil { + return err + } + if !isSet { if err = copier(toValue.Addr().Interface(), from.MapIndex(k).Interface(), opt); err != nil { return err } @@ -174,26 +210,30 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) return } - if from.Kind() == reflect.Slice && to.Kind() == reflect.Slice && fromType.ConvertibleTo(toType) { + if from.Kind() == reflect.Slice && to.Kind() == reflect.Slice { if to.IsNil() { slice := reflect.MakeSlice(reflect.SliceOf(to.Type().Elem()), from.Len(), from.Cap()) to.Set(slice) } - - for i := 0; i < from.Len(); i++ { - if to.Len() < i+1 { - to.Set(reflect.Append(to, reflect.New(to.Type().Elem()).Elem())) - } - - if !set(to.Index(i), from.Index(i), opt.DeepCopy, converters) { - // ignore error while copy slice element - err = copier(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt) + if fromType.ConvertibleTo(toType) { + for i := 0; i < from.Len(); i++ { + if to.Len() < i+1 { + to.Set(reflect.Append(to, reflect.New(to.Type().Elem()).Elem())) + } + isSet, err := set(to.Index(i), from.Index(i), opt.DeepCopy, converters) if err != nil { - continue + return err + } + if !isSet { + // ignore error while copy slice element + err = copier(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt) + if err != nil { + continue + } } } + return } - return } if fromType.Kind() != reflect.Struct || toType.Kind() != reflect.Struct { @@ -201,6 +241,13 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) return } + if len(converters) > 0 { + if ok, e := set(to, from, opt.DeepCopy, converters); e == nil && ok { + // converter supported + return + } + } + if from.Kind() == reflect.Slice || to.Kind() == reflect.Slice { isSlice = true if from.Kind() == reflect.Slice { @@ -225,6 +272,27 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) dest = indirect(to) } + if len(converters) > 0 { + if ok, e := set(dest, source, opt.DeepCopy, converters); e == nil && ok { + if isSlice { + // FIXME: maybe should check the other types? + if to.Type().Elem().Kind() == reflect.Ptr { + to.Index(i).Set(dest.Addr()) + } else { + if to.Len() < i+1 { + reflect.Append(to, dest) + } else { + to.Index(i).Set(dest) + } + } + } else { + to.Set(dest) + } + + continue + } + } + destKind := dest.Kind() initDest := false if destKind == reflect.Interface { @@ -248,19 +316,22 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) name := field.Name // Get bit flags for field - fieldFlags, _ := flgs.BitFlags[name] + fieldFlags := flgs.BitFlags[name] // Check if we should ignore copying if (fieldFlags & tagIgnore) != 0 { continue } - srcFieldName, destFieldName := getFieldName(name, flgs) - if fromField := source.FieldByName(srcFieldName); fromField.IsValid() && !shouldIgnore(fromField, opt.IgnoreEmpty) { + fieldNamesMapping := getFieldNamesMapping(mappings, fromType, toType) + + srcFieldName, destFieldName := getFieldName(name, flgs, fieldNamesMapping) + if fromField := fieldByNameOrZeroValue(source, srcFieldName); fromField.IsValid() && !shouldIgnore(fromField, opt.IgnoreEmpty) { // process for nested anonymous field destFieldNotSet := false if f, ok := dest.Type().FieldByName(destFieldName); ok { - for idx := range f.Index { + // only initialize parent embedded struct pointer in the path + for idx := range f.Index[:len(f.Index)-1] { destField := dest.FieldByIndex(f.Index[:idx+1]) if destField.Kind() != reflect.Ptr { @@ -285,10 +356,14 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) break } - toField := dest.FieldByName(destFieldName) + toField := fieldByName(dest, destFieldName, opt.CaseSensitive) if toField.IsValid() { if toField.CanSet() { - if !set(toField, fromField, opt.DeepCopy, converters) { + isSet, err := set(toField, fromField, opt.DeepCopy, converters) + if err != nil { + return err + } + if !isSet { if err := copier(toField.Addr().Interface(), fromField.Interface(), opt); err != nil { return err } @@ -317,7 +392,7 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) // Copy from from method to dest field for _, field := range deepFields(toType) { name := field.Name - srcFieldName, destFieldName := getFieldName(name, flgs) + srcFieldName, destFieldName := getFieldName(name, flgs, getFieldNamesMapping(mappings, fromType, toType)) var fromMethod reflect.Value if source.CanAddr() { @@ -327,7 +402,7 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) } if fromMethod.IsValid() && fromMethod.Type().NumIn() == 0 && fromMethod.Type().NumOut() == 1 && !shouldIgnore(fromMethod, opt.IgnoreEmpty) { - if toField := dest.FieldByName(destFieldName); toField.IsValid() && toField.CanSet() { + if toField := fieldByName(dest, destFieldName, opt.CaseSensitive); toField.IsValid() && toField.CanSet() { values := fromMethod.Call([]reflect.Value{}) if len(values) >= 1 { set(toField, values[0], opt.DeepCopy, converters) @@ -342,7 +417,11 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) if to.Len() < i+1 { to.Set(reflect.Append(to, dest.Addr())) } else { - if !set(to.Index(i), dest.Addr(), opt.DeepCopy, converters) { + isSet, err := set(to.Index(i), dest.Addr(), opt.DeepCopy, converters) + if err != nil { + return err + } + if !isSet { // ignore error while copy slice element err = copier(to.Index(i).Addr().Interface(), dest.Addr().Interface(), opt) if err != nil { @@ -354,7 +433,11 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) if to.Len() < i+1 { to.Set(reflect.Append(to, dest)) } else { - if !set(to.Index(i), dest, opt.DeepCopy, converters) { + isSet, err := set(to.Index(i), dest, opt.DeepCopy, converters) + if err != nil { + return err + } + if !isSet { // ignore error while copy slice element err = copier(to.Index(i).Addr().Interface(), dest.Interface(), opt) if err != nil { @@ -373,6 +456,31 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) return } +func getFieldNamesMapping(mappings map[converterPair]FieldNameMapping, fromType reflect.Type, toType reflect.Type) map[string]string { + var fieldNamesMapping map[string]string + + if len(mappings) > 0 { + pair := converterPair{ + SrcType: fromType, + DstType: toType, + } + if v, ok := mappings[pair]; ok { + fieldNamesMapping = v.Mapping + } + } + return fieldNamesMapping +} + +func fieldByNameOrZeroValue(source reflect.Value, fieldName string) (value reflect.Value) { + defer func() { + if err := recover(); err != nil { + value = reflect.Value{} + } + }() + + return source.FieldByName(fieldName) +} + func copyUnexportedStructFields(to, from reflect.Value) { if from.Kind() != reflect.Struct || to.Kind() != reflect.Struct || !from.Type().AssignableTo(to.Type()) { return @@ -392,14 +500,20 @@ func copyUnexportedStructFields(to, from reflect.Value) { } func shouldIgnore(v reflect.Value, ignoreEmpty bool) bool { - if !ignoreEmpty { - return false - } - - return v.IsZero() + return ignoreEmpty && v.IsZero() } +var deepFieldsLock sync.RWMutex +var deepFieldsMap = make(map[reflect.Type][]reflect.StructField) + func deepFields(reflectType reflect.Type) []reflect.StructField { + deepFieldsLock.RLock() + cache, ok := deepFieldsMap[reflectType] + deepFieldsLock.RUnlock() + if ok { + return cache + } + var res []reflect.StructField if reflectType, _ = indirectType(reflectType); reflectType.Kind() == reflect.Struct { fields := make([]reflect.StructField, 0, reflectType.NumField()) @@ -416,11 +530,13 @@ func deepFields(reflectType reflect.Type) []reflect.StructField { } } } - - return fields + res = fields } - return nil + deepFieldsLock.Lock() + deepFieldsMap[reflectType] = res + deepFieldsLock.Unlock() + return res } func indirect(reflectValue reflect.Value) reflect.Value { @@ -438,98 +554,101 @@ func indirectType(reflectType reflect.Type) (_ reflect.Type, isPtr bool) { return reflectType, isPtr } -func set(to, from reflect.Value, deepCopy bool, converters map[converterPair]TypeConverter) bool { - if from.IsValid() { - if ok, err := lookupAndCopyWithConverter(to, from, converters); err != nil { - return false - } else if ok { - return true - } - - if to.Kind() == reflect.Ptr { - // set `to` to nil if from is nil - if from.Kind() == reflect.Ptr && from.IsNil() { - to.Set(reflect.Zero(to.Type())) - return true - } else if to.IsNil() { - // `from` -> `to` - // sql.NullString -> *string - if fromValuer, ok := driverValuer(from); ok { - v, err := fromValuer.Value() - if err != nil { - return false - } - // if `from` is not valid do nothing with `to` - if v == nil { - return true - } +func set(to, from reflect.Value, deepCopy bool, converters map[converterPair]TypeConverter) (bool, error) { + if !from.IsValid() { + return true, nil + } + if ok, err := lookupAndCopyWithConverter(to, from, converters); err != nil { + return false, err + } else if ok { + return true, nil + } + + if to.Kind() == reflect.Ptr { + // set `to` to nil if from is nil + if from.Kind() == reflect.Ptr && from.IsNil() { + to.Set(reflect.Zero(to.Type())) + return true, nil + } else if to.IsNil() { + // `from` -> `to` + // sql.NullString -> *string + if fromValuer, ok := driverValuer(from); ok { + v, err := fromValuer.Value() + if err != nil { + return true, nil + } + // if `from` is not valid do nothing with `to` + if v == nil { + return true, nil } - // allocate new `to` variable with default value (eg. *string -> new(string)) - to.Set(reflect.New(to.Type().Elem())) } - // depointer `to` - to = to.Elem() + // allocate new `to` variable with default value (eg. *string -> new(string)) + to.Set(reflect.New(to.Type().Elem())) } + // depointer `to` + to = to.Elem() + } - if deepCopy { - toKind := to.Kind() - if toKind == reflect.Interface && to.IsNil() { - if reflect.TypeOf(from.Interface()) != nil { - to.Set(reflect.New(reflect.TypeOf(from.Interface())).Elem()) - toKind = reflect.TypeOf(to.Interface()).Kind() - } - } - if from.Kind() == reflect.Ptr && from.IsNil() { - return true - } - if toKind == reflect.Struct || toKind == reflect.Map || toKind == reflect.Slice { - return false + if deepCopy { + toKind := to.Kind() + if toKind == reflect.Interface && to.IsNil() { + if reflect.TypeOf(from.Interface()) != nil { + to.Set(reflect.New(reflect.TypeOf(from.Interface())).Elem()) + toKind = reflect.TypeOf(to.Interface()).Kind() } } + if from.Kind() == reflect.Ptr && from.IsNil() { + return true, nil + } + if _, ok := to.Addr().Interface().(sql.Scanner); !ok && (toKind == reflect.Struct || toKind == reflect.Map || toKind == reflect.Slice) { + return false, nil + } + } - if from.Type().ConvertibleTo(to.Type()) { - to.Set(from.Convert(to.Type())) - } else if toScanner, ok := to.Addr().Interface().(sql.Scanner); ok { - // `from` -> `to` - // *string -> sql.NullString - if from.Kind() == reflect.Ptr { - // if `from` is nil do nothing with `to` - if from.IsNil() { - return true - } - // depointer `from` - from = indirect(from) + if from.Type().ConvertibleTo(to.Type()) { + to.Set(from.Convert(to.Type())) + } else if toScanner, ok := to.Addr().Interface().(sql.Scanner); ok { + // `from` -> `to` + // *string -> sql.NullString + if from.Kind() == reflect.Ptr { + // if `from` is nil do nothing with `to` + if from.IsNil() { + return true, nil } - // `from` -> `to` - // string -> sql.NullString - // set `to` by invoking method Scan(`from`) - err := toScanner.Scan(from.Interface()) - if err != nil { - return false - } - } else if fromValuer, ok := driverValuer(from); ok { - // `from` -> `to` - // sql.NullString -> string - v, err := fromValuer.Value() - if err != nil { - return false - } - // if `from` is not valid do nothing with `to` - if v == nil { - return true - } - rv := reflect.ValueOf(v) - if rv.Type().AssignableTo(to.Type()) { - to.Set(rv) - } - } else if from.Kind() == reflect.Ptr { - return set(to, from.Elem(), deepCopy, converters) - } else { - return false + // depointer `from` + from = indirect(from) } + // `from` -> `to` + // string -> sql.NullString + // set `to` by invoking method Scan(`from`) + err := toScanner.Scan(from.Interface()) + if err != nil { + return false, nil + } + } else if fromValuer, ok := driverValuer(from); ok { + // `from` -> `to` + // sql.NullString -> string + v, err := fromValuer.Value() + if err != nil { + return false, nil + } + // if `from` is not valid do nothing with `to` + if v == nil { + return true, nil + } + rv := reflect.ValueOf(v) + if rv.Type().AssignableTo(to.Type()) { + to.Set(rv) + } else if to.CanSet() && rv.Type().ConvertibleTo(to.Type()) { + to.Set(rv.Convert(to.Type())) + } + } else if from.Kind() == reflect.Ptr { + return set(to, from.Elem(), deepCopy, converters) + } else { + return false, nil } - return true + return true, nil } // lookupAndCopyWithConverter looks up the type pair, on success the TypeConverter Fn func is called to copy src to dst field. @@ -541,7 +660,6 @@ func lookupAndCopyWithConverter(to, from reflect.Value, converters map[converter if cnv, ok := converters[pair]; ok { result, err := cnv.Fn(from.Interface()) - if err != nil { return false, err } @@ -574,7 +692,7 @@ func parseTags(tag string) (flg uint8, name string, err error) { if unicode.IsUpper([]rune(t)[0]) { name = strings.TrimSpace(t) } else { - err = errors.New("copier field name tag must be start upper case") + err = ErrFieldNameTagStartNotUpperCase } } } @@ -651,8 +769,14 @@ func checkBitFlags(flagsList map[string]uint8) (err error) { return } -func getFieldName(fieldName string, flgs flags) (srcFieldName string, destFieldName string) { +func getFieldName(fieldName string, flgs flags, fieldNameMapping map[string]string) (srcFieldName string, destFieldName string) { // get dest field name + if name, ok := fieldNameMapping[fieldName]; ok { + srcFieldName = fieldName + destFieldName = name + return + } + if srcTagName, ok := flgs.SrcNames.FieldNameToTag[fieldName]; ok { destFieldName = srcTagName if destTagName, ok := flgs.DestNames.TagToFieldName[srcTagName]; ok { @@ -686,7 +810,6 @@ func getFieldName(fieldName string, flgs flags) (srcFieldName string, destFieldN } func driverValuer(v reflect.Value) (i driver.Valuer, ok bool) { - if !v.CanAddr() { i, ok = v.Interface().(driver.Valuer) return @@ -695,3 +818,11 @@ func driverValuer(v reflect.Value) (i driver.Valuer, ok bool) { i, ok = v.Addr().Interface().(driver.Valuer) return } + +func fieldByName(v reflect.Value, name string, caseSensitive bool) reflect.Value { + if caseSensitive { + return v.FieldByName(name) + } + + return v.FieldByNameFunc(func(n string) bool { return strings.EqualFold(n, name) }) +} diff --git a/vendor/github.com/jinzhu/copier/errors.go b/vendor/github.com/jinzhu/copier/errors.go index cf7c5e7..f50ea32 100644 --- a/vendor/github.com/jinzhu/copier/errors.go +++ b/vendor/github.com/jinzhu/copier/errors.go @@ -3,8 +3,9 @@ package copier import "errors" var ( - ErrInvalidCopyDestination = errors.New("copy destination is invalid") - ErrInvalidCopyFrom = errors.New("copy from is invalid") - ErrMapKeyNotMatch = errors.New("map's key type doesn't match") - ErrNotSupported = errors.New("not supported") + ErrInvalidCopyDestination = errors.New("copy destination must be non-nil and addressable") + ErrInvalidCopyFrom = errors.New("copy from must be non-nil and addressable") + ErrMapKeyNotMatch = errors.New("map's key type doesn't match") + ErrNotSupported = errors.New("not supported") + ErrFieldNameTagStartNotUpperCase = errors.New("copier field name tag must be start upper case") ) diff --git a/vendor/modules.txt b/vendor/modules.txt index 567951e..c856b4f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -70,7 +70,7 @@ github.com/jackc/pgtype github.com/jackc/pgx/v4 github.com/jackc/pgx/v4/internal/sanitize github.com/jackc/pgx/v4/stdlib -# github.com/jinzhu/copier v0.3.5 +# github.com/jinzhu/copier v0.4.0 ## explicit; go 1.13 github.com/jinzhu/copier # github.com/jinzhu/inflection v1.0.0