package copier import "reflect" const ( noDepthLimited = -1 ) type convertFunc func(any) (any, error) type options struct { tagName string // 标签名 maxDepth int // 最大复制深度 ignoreEmpty bool // 复制时忽略空字段 caseSensitive bool // 复制时大小写敏感 must bool // 只复制具有must标识的字段 fieldNameMapping map[string]string // 字段名转映射 nameConverter func(string) string // 字段名转换函数 converters map[converterPair]convertFunc // 根据源和目标类型处理的类型转换器v convertByName map[string]convertFunc // 根据名称处理的类型转换器 } type option func(*options) type TypeConverter struct { FieldName string SrcType any DstType any Fn func(src any) (dst any, err error) } type converterPair struct { Name string SrcType reflect.Type DstType reflect.Type } func getOpt(opts ...option) *options { opt := &options{ maxDepth: noDepthLimited, tagName: defaultTag, convertByName: make(map[string]convertFunc), converters: make(map[converterPair]convertFunc), } for _, o := range opts { o(opt) } return opt } func (opt *options) NameConvert(name string) string { if opt.nameConverter != nil { name = opt.nameConverter(name) } if toname, ok := opt.fieldNameMapping[name]; ok { name = toname } return name } func (opt *options) ExceedMaxDepth(depth int) bool { return opt.maxDepth != noDepthLimited && depth > opt.maxDepth } // WithMaxDepth 设置最大复制深度 func WithMaxDepth(depth int) option { return func(o *options) { o.maxDepth = depth } } // WithIgnoreEmpty 复制时忽略空字段标识 func WithIgnoreEmpty() option { return func(o *options) { o.ignoreEmpty = true } } // WithCaseInsensitive 复制时大小写不敏感标识 func WithCaseSensitive() option { return func(o *options) { o.caseSensitive = true } } // WithMust 添加必须复制标识 func WithMust() option { return func(o *options) { o.must = true } } // WithNameConvertByName 添加根据名称处理的类型转换器 func WithTypeConvertByName(name string, f func(src any) (dst any, err error)) option { return func(o *options) { o.convertByName[name] = f } } // WithTypeConvert 添加根据源和目标类型处理的类型转换器 func WithConverters(converters ...TypeConverter) option { return func(o *options) { for i := range converters { pair := converterPair{ SrcType: reflect.TypeOf(converters[i].SrcType), DstType: reflect.TypeOf(converters[i].DstType), } o.converters[pair] = converters[i].Fn } } } // WithNameMapping 添加字段名映射 func WithNameMapping(mappings map[string]string) option { return func(o *options) { o.fieldNameMapping = mappings } } // WithNameConverter 添加字段名转换函数 func WithNameFn(fn func(string) string) option { return func(o *options) { o.nameConverter = fn } } // WithTagName 添加标签名 func WithTagName(tagName string) option { return func(o *options) { o.tagName = tagName } }