package mapstruct import ( "reflect" "time" ) // Options contains all conversion options. type Options struct { *commonOptions // StructToMap options TypeHooks map[reflect.Type]HookFunc // MapToStruct options StringTypeHooks map[reflect.Type]StringHookFunc } // Option configures conversion options. type Option func(*Options) // WithTagName sets the struct tag name to use for field mapping. func WithTagName(name string) Option { return func(o *Options) { o.TagName = name } } // WithTypeHook adds a hook for struct-to-map conversion. 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 adds a hook for map-to-struct conversion. 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 adds a field-specific hook for struct-to-map conversion. 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 adds a field-specific hook for map-to-struct conversion. func WithStringFieldHook(fieldName string, hook StringHookFunc) Option { return func(o *Options) { if o.FieldHooks == nil { o.FieldHooks = make(map[string]HookFunc) } // For map-to-struct, we need to adapt the hook type 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 returns default options with common type hooks. func defaultOptions() *Options { opts := &Options{ commonOptions: newCommonOptions(), } // Register default time.Time hooks WithTypeHook(reflect.TypeOf(time.Time{}), func(v reflect.Value, _ reflect.StructField) (any, error) { return v.Interface(), nil })(opts) WithStringTypeHook(reflect.TypeOf(time.Time{}), func(s string, _ reflect.StructField) (any, error) { return time.Parse("2006-01-02 15:04:05", s) })(opts) return opts }