Files
structx/value_setter.go
2025-09-21 12:06:32 +08:00

110 lines
2.9 KiB
Go

package structx
import (
"fmt"
"reflect"
)
// ValueSetter 值设置器接口
type ValueSetter interface {
SetFieldValue(field reflect.Value, value string) (interface{}, error)
SetSliceElementValue(elemValue reflect.Value, item interface{}, elemType reflect.Type) error
}
// defaultValueSetter 默认值设置器
type defaultValueSetter struct{}
func (ds *defaultValueSetter) SetFieldValue(field reflect.Value, value string) (interface{}, error) {
fieldType := field.Type()
if hasUnmarshalJSON(fieldType) {
if err := setUnmarshalJSONValue(field, value); err != nil {
return nil, fmt.Errorf("UnmarshalJSON失败: %w", err)
}
return field.Interface(), nil
}
if hasUnmarshalText(fieldType) {
if err := setUnmarshalTextValue(field, value); err != nil {
return nil, fmt.Errorf("UnmarshalText失败: %w", err)
}
return field.Interface(), nil
}
if fieldType.Kind() == reflect.Ptr {
return setPointerFieldValue(field, value)
}
if isTypeAlias(fieldType) {
return setTypeAliasValue(field, value)
}
if isCustomStructType(fieldType) {
return setCustomTypeValue(field, value)
}
converter, exists := typeConverters[fieldType.Kind()]
if !exists {
return nil, fmt.Errorf("不支持的类型: %s", fieldType.Kind())
}
result, err := converter(field, value)
if err != nil {
return nil, err
}
field.Set(reflect.ValueOf(result))
return result, nil
}
func (ds *defaultValueSetter) SetSliceElementValue(elemValue reflect.Value, item interface{}, elemType reflect.Type) error {
if elemType.Kind() == reflect.Ptr {
if elemValue.IsNil() {
elemValue.Set(reflect.New(elemType.Elem()))
}
return ds.SetSliceElementValue(elemValue.Elem(), item, elemType.Elem())
}
if hasUnmarshalJSON(elemType) {
return setUnmarshalJSONValue(elemValue, item)
}
switch elemType.Kind() {
case reflect.String:
elemValue.SetString(convertToString(item))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
num, err := convertToFloat64(item)
if err != nil {
return fmt.Errorf("无法转换为整型: %w", err)
}
elemValue.SetInt(int64(num))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
num, err := convertToFloat64(item)
if err != nil {
return fmt.Errorf("无法转换为无符号整型: %w", err)
}
elemValue.SetUint(uint64(num))
case reflect.Float32, reflect.Float64:
num, err := convertToFloat64(item)
if err != nil {
return fmt.Errorf("无法转换为浮点型: %w", err)
}
elemValue.SetFloat(num)
case reflect.Bool:
if b, ok := item.(bool); ok {
elemValue.SetBool(b)
} else {
return fmt.Errorf("无法转换为布尔型")
}
case reflect.Struct:
if isBasicStructType(elemType) {
return setBasicStructElement(elemValue, item)
}
return setStructElement(elemValue, item)
default:
return fmt.Errorf("不支持的切片元素类型: %s", elemType.Kind())
}
return nil
}