|
|
@@ -18,14 +18,18 @@ func AssignTo[T any](from any) (T, error) {
|
|
|
}
|
|
|
|
|
|
fromValue := reflect.ValueOf(from)
|
|
|
- retValue := reflect.ValueOf(zero)
|
|
|
+ retType := reflect.TypeOf(zero)
|
|
|
+ retValue := reflect.New(retType).Elem()
|
|
|
+ if retValue.Kind() == reflect.Ptr {
|
|
|
+ retValue.Set(reflect.New(retType.Elem()))
|
|
|
+ }
|
|
|
|
|
|
// 类型校验
|
|
|
if fromValue.Kind() != reflect.Ptr && fromValue.Kind() != reflect.Struct {
|
|
|
return zero, fserr.New("参数不是结构或结构指针")
|
|
|
}
|
|
|
|
|
|
- if fromValue.Kind() == reflect.Ptr && fromValue.Kind() != reflect.Struct {
|
|
|
+ if fromValue.Kind() == reflect.Ptr && fromValue.Elem().Kind() != reflect.Struct {
|
|
|
return zero, fserr.New("参数不是结构或结构指针")
|
|
|
}
|
|
|
|
|
|
@@ -47,11 +51,35 @@ func AssignTo[T any](from any) (T, error) {
|
|
|
retElemValue = retValue.Elem()
|
|
|
}
|
|
|
|
|
|
+ err := assignTo(fromElemValue, &retElemValue)
|
|
|
+ if err != nil {
|
|
|
+ return zero, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return retValue.Interface().(T), nil
|
|
|
+}
|
|
|
+
|
|
|
+func assignTo(fromElemValue reflect.Value, retElemValue *reflect.Value) error {
|
|
|
for i := 0; i < fromElemValue.NumField(); i++ {
|
|
|
fromField := fromElemValue.Type().Field(i)
|
|
|
- tag, err := parseAssignTag(fromField)
|
|
|
+ tagStr := fromField.Tag.Get(assignTagKey)
|
|
|
+ if strutils.IsStringEmpty(tagStr) &&
|
|
|
+ (fromField.Type.Kind() == reflect.Struct ||
|
|
|
+ (fromField.Type.Kind() == reflect.Ptr && fromField.Type.Elem().Kind() == reflect.Struct)) {
|
|
|
+ fromStructElemValue := fromElemValue.Field(i)
|
|
|
+ if fromField.Type.Kind() == reflect.Ptr {
|
|
|
+ fromStructElemValue = fromElemValue.Elem()
|
|
|
+ }
|
|
|
+
|
|
|
+ err := assignTo(fromStructElemValue, retElemValue)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ tag, err := parseAssignTag(fromField, tagStr)
|
|
|
if err != nil {
|
|
|
- return zero, err
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
if tag == nil {
|
|
|
@@ -61,7 +89,7 @@ func AssignTo[T any](from any) (T, error) {
|
|
|
fromFieldValue := fromElemValue.Field(i)
|
|
|
|
|
|
// 无效零值,不进行赋值
|
|
|
- if !fromFieldValue.IsValid() || fromFieldValue.IsNil() || fromFieldValue.IsZero() {
|
|
|
+ if !fromFieldValue.IsValid() || fromFieldValue.IsZero() {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
@@ -95,16 +123,16 @@ func AssignTo[T any](from any) (T, error) {
|
|
|
retFieldElemValue = retFieldValue.Elem()
|
|
|
}
|
|
|
|
|
|
- err = assignTo(fromFieldElemValue, retFieldElemValue, tag)
|
|
|
+ err = assignField(fromFieldElemValue, retFieldElemValue, tag)
|
|
|
if err != nil {
|
|
|
- return zero, err
|
|
|
+ return err
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return retValue.Interface(), nil
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func assignTo(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Value, tag *assignTag) error {
|
|
|
+func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Value, tag *assignTag) error {
|
|
|
fromKind := reflectutils.GroupValueKind(fromFieldElemValue)
|
|
|
retKind := reflectutils.GroupValueKind(retFieldElemValue)
|
|
|
|
|
|
@@ -117,6 +145,10 @@ func assignTo(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Value,
|
|
|
break
|
|
|
}
|
|
|
|
|
|
+ if retKind == reflect.Struct {
|
|
|
+ return assignTo(fromFieldElemValue, &retFieldElemValue)
|
|
|
+ }
|
|
|
+
|
|
|
fromAny = fromFieldElemValue.Interface()
|
|
|
case reflect.Slice:
|
|
|
if fromFieldElemValue.Elem().Kind() == reflect.String && retKind == reflect.String {
|
|
|
@@ -212,9 +244,7 @@ type assignTag struct {
|
|
|
TrimSuffix string
|
|
|
}
|
|
|
|
|
|
-func parseAssignTag(field reflect.StructField) (*assignTag, error) {
|
|
|
- tagStr := field.Tag.Get(assignTagKey)
|
|
|
-
|
|
|
+func parseAssignTag(field reflect.StructField, tagStr string) (*assignTag, error) {
|
|
|
if tagStr == assignIgnore {
|
|
|
return nil, nil
|
|
|
}
|