92 lines
2.3 KiB
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
|
|
}
|