|
|
@@ -10,76 +10,55 @@ import (
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
-func AssignTo[T any](from any) (T, error) {
|
|
|
- var zero T
|
|
|
-
|
|
|
- if from == nil {
|
|
|
- return zero, nil
|
|
|
+func AssignTo(from any, to any) error {
|
|
|
+ if from == nil || to == nil {
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
fromValue := reflect.ValueOf(from)
|
|
|
- retType := reflect.TypeOf(zero)
|
|
|
- retValue := reflect.New(retType).Elem()
|
|
|
- if retValue.Kind() == reflect.Ptr {
|
|
|
- retValue.Set(reflect.New(retType.Elem()))
|
|
|
- }
|
|
|
+ retValue := reflect.ValueOf(to)
|
|
|
|
|
|
// 类型校验
|
|
|
- if fromValue.Kind() != reflect.Ptr && fromValue.Kind() != reflect.Struct {
|
|
|
- return zero, fserr.New("参数不是结构或结构指针")
|
|
|
- }
|
|
|
-
|
|
|
- if fromValue.Kind() == reflect.Ptr && fromValue.Elem().Kind() != reflect.Struct {
|
|
|
- return zero, fserr.New("参数不是结构或结构指针")
|
|
|
- }
|
|
|
-
|
|
|
- if retValue.Kind() != reflect.Ptr && retValue.Kind() != reflect.Struct {
|
|
|
- return zero, fserr.New("返回类型不是结构或结构指针")
|
|
|
+ if !reflectutils.IsValueStructOrStructPointer(fromValue) {
|
|
|
+ return fserr.New("参数不是结构或结构指针")
|
|
|
}
|
|
|
|
|
|
- if retValue.Kind() == reflect.Ptr && retValue.Elem().Kind() != reflect.Struct {
|
|
|
- return zero, fserr.New("返回类型不是结构或结构指针")
|
|
|
+ if !reflectutils.IsValueStructPointer(retValue) {
|
|
|
+ return fserr.New("返回类型不是结构指针")
|
|
|
}
|
|
|
|
|
|
- fromElemValue := fromValue
|
|
|
- if fromValue.Kind() == reflect.Ptr {
|
|
|
- fromElemValue = fromValue.Elem()
|
|
|
- }
|
|
|
-
|
|
|
- retElemValue := retValue
|
|
|
- if retValue.Kind() == reflect.Ptr {
|
|
|
- retElemValue = retValue.Elem()
|
|
|
- }
|
|
|
+ fromElemValue := reflectutils.PointerValueElem(fromValue)
|
|
|
+ retElemValue := reflectutils.PointerValueElem(retValue)
|
|
|
|
|
|
err := assignTo(fromElemValue, &retElemValue)
|
|
|
if err != nil {
|
|
|
- return zero, err
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
- return retValue.Interface().(T), nil
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
func assignTo(fromElemValue reflect.Value, retElemValue *reflect.Value) error {
|
|
|
for i := 0; i < fromElemValue.NumField(); i++ {
|
|
|
fromField := fromElemValue.Type().Field(i)
|
|
|
+ fromFieldValue := fromElemValue.Field(i)
|
|
|
+
|
|
|
+ // 无效零值,不进行赋值
|
|
|
+ if !fromFieldValue.IsValid() || fromFieldValue.IsZero() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
tagStr := fromField.Tag.Get(assignTagKey)
|
|
|
|
|
|
// 结构上没有添加Tag, 先尝试直接按照字段赋值结构,如果失败,进一步进入内部尝试
|
|
|
if strutils.IsStringEmpty(tagStr) &&
|
|
|
- ((fromField.Type.Kind() == reflect.Struct && fromField.Type.String() != "time.Time") ||
|
|
|
- (fromField.Type.Kind() == reflect.Ptr &&
|
|
|
- fromField.Type.Elem().Kind() == reflect.Struct &&
|
|
|
- fromField.Type.Elem().String() != "time.Time")) {
|
|
|
- fromStructElemValue := fromElemValue.Field(i)
|
|
|
- if fromField.Type.Kind() == reflect.Ptr {
|
|
|
- if !fromStructElemValue.IsValid() || fromStructElemValue.IsZero() {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- fromStructElemValue = fromStructElemValue.Elem()
|
|
|
+ !reflectutils.IsValueTime(fromFieldValue) &&
|
|
|
+ !reflectutils.IsValueTimePointer(fromFieldValue) {
|
|
|
+ if !fromFieldValue.IsValid() || fromFieldValue.IsZero() {
|
|
|
+ continue
|
|
|
}
|
|
|
|
|
|
- err := assignTo(fromStructElemValue, retElemValue)
|
|
|
+ err := assignTo(reflectutils.PointerValueElem(fromFieldValue), retElemValue)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -94,18 +73,6 @@ func assignTo(fromElemValue reflect.Value, retElemValue *reflect.Value) error {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
- fromFieldValue := fromElemValue.Field(i)
|
|
|
-
|
|
|
- // 无效零值,不进行赋值
|
|
|
- if !fromFieldValue.IsValid() || fromFieldValue.IsZero() {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- fromFieldElemValue := fromFieldValue
|
|
|
- if fromFieldValue.Kind() == reflect.Ptr {
|
|
|
- fromFieldElemValue = fromFieldValue.Elem()
|
|
|
- }
|
|
|
-
|
|
|
retFieldValue := retElemValue.FieldByName(tag.ToField)
|
|
|
|
|
|
// 不存在对应的字段
|
|
|
@@ -131,6 +98,7 @@ func assignTo(fromElemValue reflect.Value, retElemValue *reflect.Value) error {
|
|
|
retFieldElemValue = retFieldValue.Elem()
|
|
|
}
|
|
|
|
|
|
+ fromFieldElemValue := reflectutils.PointerValueElem(fromFieldValue)
|
|
|
err = assignField(fromFieldElemValue, retFieldElemValue, tag)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -147,19 +115,22 @@ func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Val
|
|
|
var fromAny any
|
|
|
switch fromKind {
|
|
|
case reflect.Struct:
|
|
|
- if fromFieldElemValue.Type().String() == "time.Time" && retKind == reflect.String {
|
|
|
+ // time.Time类型的结构,接收字段是string类型,使用FormatTime的格式转换
|
|
|
+ if reflectutils.IsValueTime(fromFieldElemValue) && retKind == reflect.String {
|
|
|
fromString := fromFieldElemValue.Interface().(time.Time).Format(tag.FormatTime)
|
|
|
fromAny = trimFromString(fromString, tag)
|
|
|
break
|
|
|
}
|
|
|
|
|
|
- if fromFieldElemValue.Type().String() != "time.Time" && retKind == reflect.Struct {
|
|
|
+ // 不是time.Time类型的结构,接收字段是结构,执行结构到结构字段的赋值
|
|
|
+ if !reflectutils.IsValueTime(fromFieldElemValue) && retKind == reflect.Struct {
|
|
|
return assignTo(fromFieldElemValue, &retFieldElemValue)
|
|
|
}
|
|
|
|
|
|
+ // 直接将整个结构进行字段赋值
|
|
|
fromAny = fromFieldElemValue.Interface()
|
|
|
case reflect.Slice:
|
|
|
- if fromFieldElemValue.Elem().Kind() == reflect.String && retKind == reflect.String {
|
|
|
+ if reflectutils.IsSliceValueOf(fromFieldElemValue, reflect.String) && retKind == reflect.String {
|
|
|
fromString := strings.Join(fromFieldElemValue.Interface().([]string), tag.JoinWith)
|
|
|
fromAny = trimFromString(fromString, tag)
|
|
|
break
|
|
|
@@ -169,7 +140,7 @@ func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Val
|
|
|
case reflect.String:
|
|
|
fromString := fromFieldElemValue.String()
|
|
|
|
|
|
- if retKind == reflect.Struct && retFieldElemValue.Type().String() == "time.Time" {
|
|
|
+ if reflectutils.IsValueTime(retFieldElemValue) {
|
|
|
retTimeField, err := time.ParseInLocation(tag.ParseTime, fromString, time.Local)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -179,7 +150,7 @@ func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Val
|
|
|
break
|
|
|
}
|
|
|
|
|
|
- if retFieldElemValue.Kind() == reflect.Slice && retFieldElemValue.Elem().Kind() == reflect.String {
|
|
|
+ if reflectutils.IsSliceValueOf(retFieldElemValue, reflect.String) {
|
|
|
fromAny = strings.Split(fromString, tag.SplitWith)
|
|
|
break
|
|
|
}
|