|
|
@@ -10,7 +10,19 @@ import (
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
+type OnAssignParsedFieldTagFunc func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *AssignTag) error
|
|
|
+
|
|
|
func AssignTo(from any, to any) error {
|
|
|
+ return CustomAssignTo(from, to, func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *AssignTag) error {
|
|
|
+ if fromFieldElemValue.IsZero() {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return assignField(fromFieldElemValue, retFieldElementValue, tag)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+func CustomAssignTo(from any, to any, onParsedFieldTagFunc OnAssignParsedFieldTagFunc) error {
|
|
|
if from == nil || to == nil {
|
|
|
return nil
|
|
|
}
|
|
|
@@ -42,7 +54,7 @@ func AssignTo(from any, to any) error {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- err := assignTo(fromElemValue, &retElemValue)
|
|
|
+ err := parseStructAssignTag(fromElemValue, &retElemValue, onParsedFieldTagFunc)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -50,75 +62,7 @@ func AssignTo(from any, to any) error {
|
|
|
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
|
|
|
- }
|
|
|
-
|
|
|
- fromFieldElemValue := reflectutils.PointerValueElem(fromFieldValue)
|
|
|
-
|
|
|
- tagStr := fromField.Tag.Get(assignTagKey)
|
|
|
-
|
|
|
- // 结构类型的字段上没有添加Tag, 先尝试直接按照字段赋值
|
|
|
- if strutils.IsStringEmpty(tagStr) && fromFieldElemValue.Kind() == reflect.Struct &&
|
|
|
- !reflectutils.IsValueTime(fromFieldElemValue) {
|
|
|
- err := assignTo(fromFieldElemValue, retElemValue)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- tag, err := parseAssignTag(fromField, tagStr)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- if tag == nil {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- retFieldValue := retElemValue.FieldByName(tag.ToField)
|
|
|
-
|
|
|
- // 不存在对应的字段
|
|
|
- if !retFieldValue.IsValid() {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- retFieldElemValue := retFieldValue
|
|
|
- if retFieldValue.Kind() == reflect.Pointer {
|
|
|
- if !retFieldValue.IsValid() {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- if !retFieldValue.CanSet() {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- // 空值针,初始化
|
|
|
- if retFieldValue.IsNil() {
|
|
|
- retFieldValue.Set(reflect.New(retFieldValue.Type().Elem()))
|
|
|
- }
|
|
|
-
|
|
|
- retFieldElemValue = retFieldValue.Elem()
|
|
|
- }
|
|
|
-
|
|
|
- err = assignField(fromFieldElemValue, retFieldElemValue, tag)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func assignField(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)
|
|
|
|
|
|
@@ -134,7 +78,9 @@ func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Val
|
|
|
|
|
|
// 不是time.Time类型的结构,接收字段是结构,执行结构到结构字段的赋值
|
|
|
if !reflectutils.IsValueTime(fromFieldElemValue) && retKind == reflect.Struct {
|
|
|
- return assignTo(fromFieldElemValue, &retFieldElemValue)
|
|
|
+ return parseStructAssignTag(fromFieldElemValue, &retFieldElemValue, func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *AssignTag) error {
|
|
|
+ return assignField(fromFieldElemValue, retFieldElementValue, tag)
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
// 直接将整个结构进行字段赋值
|
|
|
@@ -187,7 +133,7 @@ func assignField(fromFieldElemValue reflect.Value, retFieldElemValue reflect.Val
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func assignTrimFromString(fromString string, tag *assignTag) string {
|
|
|
+func assignTrimFromString(fromString string, tag *AssignTag) string {
|
|
|
if strutils.IsStringNotEmpty(tag.Trim) {
|
|
|
return strings.Trim(fromString, tag.Trim)
|
|
|
} else {
|
|
|
@@ -203,6 +149,78 @@ func assignTrimFromString(fromString string, tag *assignTag) string {
|
|
|
return fromString
|
|
|
}
|
|
|
|
|
|
+func parseStructAssignTag(fromElemValue reflect.Value, retElemValue *reflect.Value, onParsedFieldTagFunc OnAssignParsedFieldTagFunc) error {
|
|
|
+ for i := 0; i < fromElemValue.NumField(); i++ {
|
|
|
+ fromField := fromElemValue.Type().Field(i)
|
|
|
+ fromFieldValue := fromElemValue.Field(i)
|
|
|
+
|
|
|
+ // 无效值
|
|
|
+ if !fromFieldValue.IsValid() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if fromFieldValue.Kind() == reflect.Pointer && fromFieldValue.IsNil() {
|
|
|
+ fromFieldValue.Set(reflect.New(fromField.Type.Elem()))
|
|
|
+ }
|
|
|
+
|
|
|
+ fromFieldElemValue := reflectutils.PointerValueElem(fromFieldValue)
|
|
|
+
|
|
|
+ tagStr := fromField.Tag.Get(assignTagKey)
|
|
|
+
|
|
|
+ // 结构类型的字段上没有添加Tag, 先尝试直接按照字段赋值
|
|
|
+ if strutils.IsStringEmpty(tagStr) && fromFieldElemValue.Kind() == reflect.Struct &&
|
|
|
+ !reflectutils.IsValueTime(fromFieldElemValue) {
|
|
|
+ err := parseStructAssignTag(fromFieldElemValue, retElemValue, onParsedFieldTagFunc)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ tag, err := parseAssignTag(fromField, tagStr)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if tag == nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ retFieldValue := retElemValue.FieldByName(tag.ToField)
|
|
|
+
|
|
|
+ // 不存在对应的字段
|
|
|
+ if !retFieldValue.IsValid() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ retFieldElemValue := retFieldValue
|
|
|
+ if retFieldValue.Kind() == reflect.Pointer {
|
|
|
+ if !retFieldValue.IsValid() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if !retFieldValue.CanSet() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // 空值针,初始化
|
|
|
+ if retFieldValue.IsNil() {
|
|
|
+ retFieldValue.Set(reflect.New(retFieldValue.Type().Elem()))
|
|
|
+ }
|
|
|
+
|
|
|
+ retFieldElemValue = retFieldValue.Elem()
|
|
|
+ }
|
|
|
+
|
|
|
+ err = onParsedFieldTagFunc(fromField.Name, fromFieldElemValue, retFieldElemValue, tag)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
const (
|
|
|
assignDefaultStringSliceSeparator = "::"
|
|
|
assignTagPartSeparator = ";"
|
|
|
@@ -222,7 +240,7 @@ const (
|
|
|
assignTrimSuffix = "trimSuffix"
|
|
|
)
|
|
|
|
|
|
-type assignTag struct {
|
|
|
+type AssignTag struct {
|
|
|
ToField string
|
|
|
ParseTime string
|
|
|
FormatTime string
|
|
|
@@ -233,12 +251,12 @@ type assignTag struct {
|
|
|
TrimSuffix string
|
|
|
}
|
|
|
|
|
|
-func parseAssignTag(field reflect.StructField, tagStr string) (*assignTag, error) {
|
|
|
+func parseAssignTag(field reflect.StructField, tagStr string) (*AssignTag, error) {
|
|
|
if tagStr == assignIgnore {
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
- tag := &assignTag{
|
|
|
+ tag := &AssignTag{
|
|
|
ToField: field.Name,
|
|
|
ParseTime: time.DateTime,
|
|
|
FormatTime: time.DateTime,
|