拆开文件夹

This commit is contained in:
Yun
2025-09-21 12:06:32 +08:00
parent 0e0f076fc4
commit e57caf3080
6 changed files with 599 additions and 572 deletions
+324
View File
@@ -0,0 +1,324 @@
package structx
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"strings"
"code.yun.ink/pkg/convx"
)
// 工具函数
func getJSONTagName(field reflect.StructField) string {
jsonTag := field.Tag.Get("json")
if jsonTag == "" || jsonTag == "-" {
return field.Name
}
return strings.Split(jsonTag, ",")[0]
}
func isBasicStructType(t reflect.Type) bool {
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
return basicStructTypes[t.String()]
}
func hasUnmarshalJSON(t reflect.Type) bool {
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
unmarshalerType := reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
return t.Implements(unmarshalerType) || reflect.PtrTo(t).Implements(unmarshalerType)
}
func hasUnmarshalText(t reflect.Type) bool {
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
textUnmarshalerType := reflect.TypeOf((*interface {
UnmarshalText([]byte) error
})(nil)).Elem()
return t.Implements(textUnmarshalerType) || reflect.PtrTo(t).Implements(textUnmarshalerType)
}
func setUnmarshalJSONValue(field reflect.Value, value interface{}) error {
jsonBytes, err := json.Marshal(value)
if err != nil {
return err
}
var fieldAddr reflect.Value
if field.CanAddr() {
fieldAddr = field.Addr()
} else {
temp := reflect.New(field.Type())
temp.Elem().Set(field)
fieldAddr = temp
}
if unmarshaler, ok := fieldAddr.Interface().(json.Unmarshaler); ok {
return unmarshaler.UnmarshalJSON(jsonBytes)
}
return fmt.Errorf("类型未实现Unmarshaler")
}
func setUnmarshalTextValue(field reflect.Value, value string) error {
var fieldAddr reflect.Value
if field.CanAddr() {
fieldAddr = field.Addr()
} else {
temp := reflect.New(field.Type())
temp.Elem().Set(field)
fieldAddr = temp
}
if unmarshaler, ok := fieldAddr.Interface().(interface {
UnmarshalText([]byte) error
}); ok {
return unmarshaler.UnmarshalText([]byte(value))
}
return fmt.Errorf("类型未实现UnmarshalText")
}
func setBasicStructValue(field reflect.Value, value string) error {
if hasUnmarshalText(field.Type()) {
return setUnmarshalTextValue(field, value)
}
return json.Unmarshal([]byte(value), field.Addr().Interface())
}
func setPointerFieldValue(field reflect.Value, value string) (interface{}, error) {
if field.Kind() != reflect.Ptr {
return nil, fmt.Errorf("期望指针类型")
}
if field.IsNil() {
field.Set(reflect.New(field.Type().Elem()))
}
return new(defaultValueSetter).SetFieldValue(field.Elem(), value)
}
func isTypeAlias(t reflect.Type) bool {
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
return t.PkgPath() != "" && basicKinds[t.Kind()]
}
func setTypeAliasValue(field reflect.Value, value string) (interface{}, error) {
baseType := getBaseTypeFromAlias(field.Type())
if baseType == nil {
return nil, fmt.Errorf("无法获取基础类型")
}
converter, exists := typeConverters[baseType.Kind()]
if !exists {
return nil, fmt.Errorf("不支持的基础类型")
}
baseValue := reflect.New(baseType).Elem()
result, err := converter(baseValue, value)
if err != nil {
return nil, err
}
convertedValue, err := convertToTypeAlias(field.Type(), result)
if err != nil {
return nil, err
}
field.Set(reflect.ValueOf(convertedValue))
return convertedValue, nil
}
func isCustomStructType(t reflect.Type) bool {
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
return t.PkgPath() != "" && !isBasicStructType(t) && !isTypeAlias(t) && t.Kind() == reflect.Struct
}
func setCustomTypeValue(field reflect.Value, value string) (interface{}, error) {
if hasUnmarshalText(field.Type()) {
if err := setUnmarshalTextValue(field, value); err != nil {
return nil, err
}
return field.Interface(), nil
}
var jsonData interface{}
if err := json.Unmarshal([]byte(value), &jsonData); err != nil {
return nil, err
}
jsonBytes, err := json.Marshal(jsonData)
if err != nil {
return nil, err
}
if err := json.Unmarshal(jsonBytes, field.Addr().Interface()); err != nil {
return nil, err
}
return field.Interface(), nil
}
func setBasicStructElement(elemValue reflect.Value, item interface{}) error {
return setStructElement(elemValue, item)
}
func setStructElement(elemValue reflect.Value, item interface{}) error {
jsonBytes, err := json.Marshal(item)
if err != nil {
return err
}
return json.Unmarshal(jsonBytes, elemValue.Addr().Interface())
}
func convertToString(item interface{}) string {
if str, ok := item.(string); ok {
return str
}
return fmt.Sprintf("%v", item)
}
func convertToFloat64(item interface{}) (float64, error) {
switch v := item.(type) {
case float64:
return v, nil
case int, int32, int64:
return float64(reflect.ValueOf(v).Int()), nil
case uint, uint32, uint64:
return float64(reflect.ValueOf(v).Uint()), nil
case float32:
return float64(v), nil
default:
return 0, fmt.Errorf("无法转换为数字")
}
}
func getBaseTypeFromAlias(aliasType reflect.Type) reflect.Type {
if aliasType.Kind() == reflect.Ptr {
aliasType = aliasType.Elem()
}
switch aliasType.Kind() {
case reflect.String:
return reflect.TypeOf("")
case reflect.Int:
return reflect.TypeOf(int(0))
case reflect.Int8:
return reflect.TypeOf(int8(0))
case reflect.Int16:
return reflect.TypeOf(int16(0))
case reflect.Int32:
return reflect.TypeOf(int32(0))
case reflect.Int64:
return reflect.TypeOf(int64(0))
case reflect.Uint:
return reflect.TypeOf(uint(0))
case reflect.Uint8:
return reflect.TypeOf(uint8(0))
case reflect.Uint16:
return reflect.TypeOf(uint16(0))
case reflect.Uint32:
return reflect.TypeOf(uint32(0))
case reflect.Uint64:
return reflect.TypeOf(uint64(0))
case reflect.Float32:
return reflect.TypeOf(float32(0))
case reflect.Float64:
return reflect.TypeOf(float64(0))
case reflect.Bool:
return reflect.TypeOf(false)
default:
return nil
}
}
func convertToTypeAlias(aliasType reflect.Type, value interface{}) (interface{}, error) {
if aliasType.Kind() == reflect.Ptr {
elemType := aliasType.Elem()
newValue := reflect.New(elemType)
elemValue := newValue.Elem()
converted, err := convertValueToType(value, elemType)
if err != nil {
return nil, err
}
elemValue.Set(reflect.ValueOf(converted))
return newValue.Interface(), nil
}
return convertValueToType(value, aliasType)
}
func convertValueToType(value interface{}, targetType reflect.Type) (interface{}, error) {
valueType := reflect.TypeOf(value)
if valueType.AssignableTo(targetType) {
return value, nil
}
if valueType.ConvertibleTo(targetType) {
return reflect.ValueOf(value).Convert(targetType).Interface(), nil
}
return nil, fmt.Errorf("无法转换类型")
}
// 类型转换函数
func convertBool(field reflect.Value, value string) (interface{}, error) {
return convx.ToBool(value)
}
func convertInt[T int | int8 | int16 | int32 | int64](field reflect.Value, value string) (interface{}, error) {
bits := field.Type().Bits()
intVal, err := strconv.ParseInt(value, 10, bits)
if err != nil {
return nil, err
}
return T(intVal), nil
}
func convertUint[T uint | uint8 | uint16 | uint32 | uint64](field reflect.Value, value string) (interface{}, error) {
bits := field.Type().Bits()
uintVal, err := strconv.ParseUint(value, 10, bits)
if err != nil {
return nil, err
}
return T(uintVal), nil
}
func convertFloat[T float32 | float64](field reflect.Value, value string) (interface{}, error) {
bits := field.Type().Bits()
floatVal, err := strconv.ParseFloat(value, bits)
if err != nil {
return nil, err
}
return T(floatVal), nil
}
func convertString(field reflect.Value, value string) (interface{}, error) {
return value, nil
}
func convertSlice(field reflect.Value, value string) (interface{}, error) {
var result []interface{}
if err := json.Unmarshal([]byte(value), &result); err != nil {
return nil, err
}
return result, nil
}
func convertArray(field reflect.Value, value string) (interface{}, error) {
var result []interface{}
if err := json.Unmarshal([]byte(value), &result); err != nil {
return nil, err
}
return result, nil
}
func convertMap(field reflect.Value, value string) (interface{}, error) {
return nil, fmt.Errorf("map转换未实现")
}