fox/mapstruct/options.go

92 lines
2.3 KiB
Go

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
}