fox/mapstruct/options.go

108 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package mapstruct
import (
"fmt"
"reflect"
"time"
)
// HookFunc 定义字段转换钩子函数类型
type HookFunc func(reflect.Value, reflect.StructField) (any, error)
// StringHookFunc 定义字符串到值的转换钩子函数类型
type StringHookFunc func(string, reflect.StructField) (any, error)
// Options 包含所有转换选项
type Options struct {
TagName string // 使用的结构体标签名称
TypeHooks map[reflect.Type]HookFunc // 类型级别的钩子
StringTypeHooks map[reflect.Type]StringHookFunc // 字符串到类型的钩子
FieldHooks map[string]HookFunc // 字段级别的钩子
}
// Option 是配置选项的函数类型
type Option func(*Options)
// WithTagName 设置结构体标签名称
func WithTagName(name string) Option {
return func(o *Options) {
o.TagName = name
}
}
// WithTypeHook 添加类型级别的转换钩子
func WithTypeHook(typ reflect.Type, hook HookFunc) Option {
return func(o *Options) {
if o.TypeHooks == nil {
o.TypeHooks = make(map[reflect.Type]HookFunc)
}
o.TypeHooks[typ] = hook
}
}
// WithStringTypeHook 添加字符串到类型的转换钩子
func WithStringTypeHook(typ reflect.Type, hook StringHookFunc) Option {
return func(o *Options) {
if o.StringTypeHooks == nil {
o.StringTypeHooks = make(map[reflect.Type]StringHookFunc)
}
o.StringTypeHooks[typ] = hook
}
}
// WithFieldHook 添加字段级别的转换钩子
func WithFieldHook(fieldName string, hook HookFunc) Option {
return func(o *Options) {
if o.FieldHooks == nil {
o.FieldHooks = make(map[string]HookFunc)
}
o.FieldHooks[fieldName] = hook
}
}
//// WithStringFieldHook 添加字段级别的字符串转换钩子
//func WithStringFieldHook(fieldName string, hook StringHookFunc) Option {
// return func(o *Options) {
// if o.FieldHooks == nil {
// o.FieldHooks = make(map[string]HookFunc)
// }
// // 适配器将StringHookFunc转换为HookFunc
// o.FieldHooks[fieldName] = func(v reflect.Value, f reflect.StructField) (any, error) {
// if v.Kind() != reflect.String {
// return nil, nil
// }
// return hook(v.String(), f)
// }
// }
//}
// defaultOptions 返回默认配置选项
func defaultOptions() *Options {
opts := &Options{
TagName: "json", // 默认使用json标签
}
// 注册默认的时间类型钩子
WithStringTypeHook(reflect.TypeOf(time.Time{}), func(value string, _ reflect.StructField) (any, error) {
// 尝试多种常见时间格式
formats := []string{
"2006-01-02 15:04:05", // 标准格式
"2006-01-02", // 仅日期
time.RFC3339, // ISO8601格式
"2006/01/02 15:04:05", // 斜杠分隔
"2006/01/02", // 斜杠分隔仅日期
"02-Jan-2006", // 英文月份缩写
}
for _, layout := range formats {
if t, err := time.Parse(layout, value); err == nil {
return t, nil
}
}
return nil, fmt.Errorf("无法解析时间字符串: %s", value)
})(opts)
return opts
}