usage.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. package assign
  2. import (
  3. "git.sxidc.com/go-tools/utils/reflectutils"
  4. "git.sxidc.com/go-tools/utils/strutils"
  5. "github.com/pkg/errors"
  6. "reflect"
  7. "strings"
  8. "time"
  9. )
  10. func DefaultUsage(from any, to any) error {
  11. return UseTag(from, to,
  12. func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *Tag) error {
  13. if fromFieldElemValue.IsZero() {
  14. return nil
  15. }
  16. return defaultCallback(fromFieldElemValue, retFieldElementValue, tag)
  17. })
  18. }
  19. func defaultCallback(fromFieldElemValue reflect.Value, toFieldElemValue reflect.Value, tag *Tag) error {
  20. fromKind := reflectutils.GroupValueKind(fromFieldElemValue)
  21. toKind := reflectutils.GroupValueKind(toFieldElemValue)
  22. var fromAny any
  23. switch fromKind {
  24. case reflect.Struct:
  25. // time.Time类型的结构,接收字段是string类型,使用FormatTime的格式转换
  26. if reflectutils.IsValueTime(fromFieldElemValue) && toKind == reflect.String {
  27. fromString := fromFieldElemValue.Interface().(time.Time).Format(tag.TimeLayout)
  28. fromAny = trimFromString(fromString, tag)
  29. break
  30. }
  31. // 不是time.Time类型的结构,接收字段是结构,执行结构到结构字段的赋值
  32. if !reflectutils.IsValueTime(fromFieldElemValue) && toKind == reflect.Struct {
  33. return parseTag(fromFieldElemValue, &toFieldElemValue, func(fromFieldName string, fromFieldElemValue reflect.Value, toFieldElementValue reflect.Value, tag *Tag) error {
  34. return defaultCallback(fromFieldElemValue, toFieldElementValue, tag)
  35. })
  36. }
  37. // 直接将整个结构进行字段赋值
  38. fromAny = fromFieldElemValue.Interface()
  39. case reflect.Slice:
  40. fromFieldElementElemType := reflectutils.PointerTypeElem(fromFieldElemValue.Type().Elem())
  41. if fromFieldElementElemType.Kind() == reflect.String && toKind == reflect.String {
  42. stringSlice := make([]string, 0)
  43. for i := 0; i < fromFieldElemValue.Len(); i++ {
  44. stringSlice = append(stringSlice, reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(string))
  45. }
  46. fromString := strings.Join(stringSlice, tag.JoinWith)
  47. fromAny = trimFromString(fromString, tag)
  48. break
  49. }
  50. if fromFieldElementElemType.Kind() == reflect.Struct &&
  51. reflectutils.IsTypeTime(fromFieldElementElemType) &&
  52. toFieldElemValue.Type().Kind() == reflect.Slice &&
  53. reflectutils.PointerTypeElem(toFieldElemValue.Type().Elem()).Kind() == reflect.String {
  54. stringSlice := make([]string, 0)
  55. for i := 0; i < fromFieldElemValue.Len(); i++ {
  56. fromString := reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(time.Time).Format(tag.TimeLayout)
  57. stringSlice = append(stringSlice, trimFromString(fromString, tag))
  58. }
  59. fromAny = stringSlice
  60. break
  61. }
  62. if fromFieldElementElemType.Kind() == reflect.String &&
  63. toFieldElemValue.Type().Kind() == reflect.Slice &&
  64. reflectutils.PointerTypeElem(toFieldElemValue.Type().Elem()).Kind() == reflect.Struct &&
  65. reflectutils.IsTypeTime(reflectutils.PointerTypeElem(toFieldElemValue.Type().Elem())) {
  66. timeSlice := make([]time.Time, 0)
  67. for i := 0; i < fromFieldElemValue.Len(); i++ {
  68. timeParsed, err := time.ParseInLocation(tag.TimeLayout, reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(string), time.Local)
  69. if err != nil {
  70. return err
  71. }
  72. timeSlice = append(timeSlice, timeParsed)
  73. }
  74. fromAny = timeSlice
  75. break
  76. }
  77. fromAny = fromFieldElemValue.Interface()
  78. case reflect.String:
  79. fromString := fromFieldElemValue.String()
  80. if reflectutils.IsValueTime(toFieldElemValue) {
  81. toTimeField, err := time.ParseInLocation(tag.TimeLayout, fromString, time.Local)
  82. if err != nil {
  83. return err
  84. }
  85. fromAny = toTimeField
  86. break
  87. }
  88. if reflectutils.IsSliceValueOf(toFieldElemValue, reflect.String) {
  89. fromAny = strings.Split(fromString, tag.SplitWith)
  90. break
  91. }
  92. fromAny = trimFromString(fromString, tag)
  93. default:
  94. fromAny = fromFieldElemValue.Interface()
  95. }
  96. err := assignTo(toKind, fromAny, toFieldElemValue)
  97. if err != nil {
  98. return err
  99. }
  100. return nil
  101. }
  102. func assignTo(toKind reflect.Kind, fromAny any, toFieldElemValue reflect.Value) error {
  103. switch toKind {
  104. case reflect.Int64:
  105. return reflectutils.AssignInt64Value(fromAny, toFieldElemValue)
  106. case reflect.Uint64:
  107. return reflectutils.AssignUint64Value(fromAny, toFieldElemValue)
  108. case reflect.Float64:
  109. return reflectutils.AssignFloat64Value(fromAny, toFieldElemValue)
  110. case reflect.Bool:
  111. return reflectutils.AssignBoolValue(fromAny, toFieldElemValue)
  112. case reflect.String:
  113. return reflectutils.AssignStringValue(fromAny, toFieldElemValue)
  114. case reflect.Slice:
  115. return assignSlice(fromAny, toFieldElemValue)
  116. default:
  117. toFieldElemValue.Set(reflect.ValueOf(fromAny))
  118. return nil
  119. }
  120. }
  121. func trimFromString(fromString string, tag *Tag) string {
  122. if strutils.IsStringNotEmpty(tag.Trim) {
  123. return strings.Trim(fromString, tag.Trim)
  124. } else {
  125. if strutils.IsStringNotEmpty(tag.TrimPrefix) {
  126. return strings.TrimPrefix(fromString, tag.TrimPrefix)
  127. }
  128. if strutils.IsStringNotEmpty(tag.TrimSuffix) {
  129. return strings.TrimSuffix(fromString, tag.TrimSuffix)
  130. }
  131. }
  132. return fromString
  133. }
  134. func assignSlice(fromAny any, toFieldElemValue reflect.Value) error {
  135. fromElemValue := reflectutils.PointerValueElem(reflect.ValueOf(fromAny))
  136. if fromElemValue.Kind() != reflect.Slice {
  137. return errors.New("不支持的操作:试图将非slice类型字段赋值给slice类型字段")
  138. }
  139. if toFieldElemValue.Kind() != reflect.Slice {
  140. return errors.New("不支持的操作:试图将slice类型字段赋值给非slice类型字段")
  141. }
  142. // 构造slice
  143. sliceValue := reflect.MakeSlice(toFieldElemValue.Type(), 0, 0)
  144. // 遍历from slice
  145. for i := 0; i < fromElemValue.Len(); i++ {
  146. // 获取from slice中元素的Value
  147. fromElementValue := fromElemValue.Index(i)
  148. // 获取from slice中元素的ElemValue
  149. fromElementElemValue := reflectutils.PointerValueElem(fromElementValue)
  150. // 获取from slice中元素是nil指针
  151. if fromElementValue.Kind() == reflect.Pointer && fromElementValue.IsNil() {
  152. fromElementElemValue = reflect.New(fromElementElemValue.Type()).Elem()
  153. }
  154. if fromElementElemValue.Kind() == reflect.Slice {
  155. if toFieldElemValue.Type().Elem().Kind() != reflect.Slice {
  156. return errors.New("不支持的操作:试图将slice类型字段赋值给非slice类型字段")
  157. }
  158. toSliceElementValue := reflect.MakeSlice(toFieldElemValue.Type().Elem(), 0, 0)
  159. err := assignSlice(fromElementElemValue.Interface(), toSliceElementValue)
  160. if err != nil {
  161. return err
  162. }
  163. for j := 0; j < toSliceElementValue.Len(); j++ {
  164. if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
  165. sliceValue = reflect.Append(sliceValue, toSliceElementValue.Index(i).Addr())
  166. } else {
  167. sliceValue = reflect.Append(sliceValue, toSliceElementValue.Index(i))
  168. }
  169. }
  170. continue
  171. }
  172. var toElementElemValue reflect.Value
  173. if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
  174. if toFieldElemValue.Type().Elem().Elem().Kind() == fromElementElemValue.Kind() &&
  175. toFieldElemValue.Type().Elem().Elem().String() == fromElementElemValue.Type().String() {
  176. toElementElemValue = fromElementElemValue
  177. } else {
  178. toElementElemValue = reflect.New(toFieldElemValue.Type().Elem().Elem()).Elem()
  179. }
  180. } else {
  181. if toFieldElemValue.Type().Elem().Kind() == fromElementElemValue.Kind() &&
  182. toFieldElemValue.Type().Elem().String() == fromElementElemValue.String() {
  183. toElementElemValue = fromElementValue
  184. } else {
  185. toElementElemValue = reflect.New(toFieldElemValue.Type().Elem()).Elem()
  186. }
  187. }
  188. if fromElementElemValue.Kind() == reflect.Struct {
  189. if reflectutils.IsValueTime(fromElementElemValue) {
  190. if !reflectutils.IsValueTime(toElementElemValue) {
  191. return errors.New("无法从time.Time赋值到不是time.Time的结构")
  192. }
  193. if toElementElemValue.Type().Kind() == reflect.Pointer {
  194. toElementElemValue.Set(fromElementElemValue.Addr())
  195. } else {
  196. toElementElemValue.Set(fromElementElemValue)
  197. }
  198. } else {
  199. err := DefaultUsage(fromElementElemValue.Interface(), toElementElemValue.Addr().Interface())
  200. if err != nil {
  201. return err
  202. }
  203. }
  204. if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
  205. sliceValue = reflect.Append(sliceValue, toElementElemValue.Addr())
  206. } else {
  207. sliceValue = reflect.Append(sliceValue, toElementElemValue)
  208. }
  209. continue
  210. }
  211. toElementKind := reflectutils.GroupValueKind(toElementElemValue)
  212. err := assignTo(toElementKind, fromElementElemValue.Interface(), toElementElemValue)
  213. if err != nil {
  214. return err
  215. }
  216. if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
  217. sliceValue = reflect.Append(sliceValue, toElementElemValue.Addr())
  218. } else {
  219. sliceValue = reflect.Append(sliceValue, toElementElemValue)
  220. }
  221. }
  222. toFieldElemValue.Set(sliceValue)
  223. return nil
  224. }