fox/mapstruct/hooks.go

82 lines
2.1 KiB
Go
Raw Normal View History

package mapstruct
import (
"fmt"
"reflect"
"strconv"
)
// applyStructToMapHook applies hooks for struct-to-map conversion.
func applyStructToMapHook(v reflect.Value, field reflect.StructField, opts *Options) (any, bool, error) {
// Check field-specific hooks first
if hook, ok := opts.FieldHooks[field.Name]; ok {
result, err := hook(v, field)
return result, true, err
}
// Check type hooks
if hook, ok := opts.TypeHooks[v.Type()]; ok {
result, err := hook(v, field)
return result, true, err
}
// Handle pointers
if v.Kind() == reflect.Ptr {
if v.IsNil() {
return nil, true, nil
}
v = v.Elem()
if hook, ok := opts.TypeHooks[v.Type()]; ok {
result, err := hook(v, field)
return result, true, err
}
}
return nil, false, nil
}
// applyMapToStructHook applies hooks for map-to-struct conversion.
func applyMapToStructHook(value string, field reflect.StructField, opts *Options) (any, error) {
// Check field-specific hooks
if hook, ok := opts.FieldHooks[field.Name]; ok {
return hook(reflect.ValueOf(value), field)
}
// Check type hooks
if hook, ok := opts.StringTypeHooks[field.Type]; ok {
return hook(value, field)
}
// Handle basic types
switch field.Type.Kind() {
case reflect.String:
return value, nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.ParseInt(value, 10, 64)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return strconv.ParseUint(value, 10, 64)
case reflect.Float32, reflect.Float64:
return strconv.ParseFloat(value, 64)
case reflect.Bool:
return strconv.ParseBool(value)
default:
return nil, fmt.Errorf("unsupported type: %s", field.Type.String())
}
}
//// getFieldName extracts the field name from struct tags.
//func getFieldName(field reflect.StructField, tagName string) (string, bool) {
// if tag, ok := field.Tag.Lookup(tagName); ok {
// if tag == "-" {
// return "", true
// }
// if commaIdx := strings.Index(tag, ","); commaIdx != -1 {
// tag = tag[:commaIdx]
// }
// if tag != "" {
// return tag, false
// }
// }
// return field.Name, false
//}