gconv_convert.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gconv
  7. import (
  8. "reflect"
  9. "time"
  10. "github.com/gogf/gf/v2/os/gtime"
  11. )
  12. // Convert converts the variable `fromValue` to the type `toTypeName`, the type `toTypeName` is specified by string.
  13. // The optional parameter `extraParams` is used for additional necessary parameter for this conversion.
  14. // It supports common types conversion as its conversion based on type name string.
  15. func Convert(fromValue interface{}, toTypeName string, extraParams ...interface{}) interface{} {
  16. return doConvert(doConvertInput{
  17. FromValue: fromValue,
  18. ToTypeName: toTypeName,
  19. ReferValue: nil,
  20. Extra: extraParams,
  21. })
  22. }
  23. type doConvertInput struct {
  24. FromValue interface{} // Value that is converted from.
  25. ToTypeName string // Target value type name in string.
  26. ReferValue interface{} // Referred value, a value in type `ToTypeName`.
  27. Extra []interface{} // Extra values for implementing the converting.
  28. // Marks that the value is already converted and set to `ReferValue`. Caller can ignore the returned result.
  29. // It is an attribute for internal usage purpose.
  30. alreadySetToReferValue bool
  31. }
  32. // doConvert does commonly use types converting.
  33. func doConvert(in doConvertInput) (convertedValue interface{}) {
  34. switch in.ToTypeName {
  35. case "int":
  36. return Int(in.FromValue)
  37. case "*int":
  38. if _, ok := in.FromValue.(*int); ok {
  39. return in.FromValue
  40. }
  41. v := Int(in.FromValue)
  42. return &v
  43. case "int8":
  44. return Int8(in.FromValue)
  45. case "*int8":
  46. if _, ok := in.FromValue.(*int8); ok {
  47. return in.FromValue
  48. }
  49. v := Int8(in.FromValue)
  50. return &v
  51. case "int16":
  52. return Int16(in.FromValue)
  53. case "*int16":
  54. if _, ok := in.FromValue.(*int16); ok {
  55. return in.FromValue
  56. }
  57. v := Int16(in.FromValue)
  58. return &v
  59. case "int32":
  60. return Int32(in.FromValue)
  61. case "*int32":
  62. if _, ok := in.FromValue.(*int32); ok {
  63. return in.FromValue
  64. }
  65. v := Int32(in.FromValue)
  66. return &v
  67. case "int64":
  68. return Int64(in.FromValue)
  69. case "*int64":
  70. if _, ok := in.FromValue.(*int64); ok {
  71. return in.FromValue
  72. }
  73. v := Int64(in.FromValue)
  74. return &v
  75. case "uint":
  76. return Uint(in.FromValue)
  77. case "*uint":
  78. if _, ok := in.FromValue.(*uint); ok {
  79. return in.FromValue
  80. }
  81. v := Uint(in.FromValue)
  82. return &v
  83. case "uint8":
  84. return Uint8(in.FromValue)
  85. case "*uint8":
  86. if _, ok := in.FromValue.(*uint8); ok {
  87. return in.FromValue
  88. }
  89. v := Uint8(in.FromValue)
  90. return &v
  91. case "uint16":
  92. return Uint16(in.FromValue)
  93. case "*uint16":
  94. if _, ok := in.FromValue.(*uint16); ok {
  95. return in.FromValue
  96. }
  97. v := Uint16(in.FromValue)
  98. return &v
  99. case "uint32":
  100. return Uint32(in.FromValue)
  101. case "*uint32":
  102. if _, ok := in.FromValue.(*uint32); ok {
  103. return in.FromValue
  104. }
  105. v := Uint32(in.FromValue)
  106. return &v
  107. case "uint64":
  108. return Uint64(in.FromValue)
  109. case "*uint64":
  110. if _, ok := in.FromValue.(*uint64); ok {
  111. return in.FromValue
  112. }
  113. v := Uint64(in.FromValue)
  114. return &v
  115. case "float32":
  116. return Float32(in.FromValue)
  117. case "*float32":
  118. if _, ok := in.FromValue.(*float32); ok {
  119. return in.FromValue
  120. }
  121. v := Float32(in.FromValue)
  122. return &v
  123. case "float64":
  124. return Float64(in.FromValue)
  125. case "*float64":
  126. if _, ok := in.FromValue.(*float64); ok {
  127. return in.FromValue
  128. }
  129. v := Float64(in.FromValue)
  130. return &v
  131. case "bool":
  132. return Bool(in.FromValue)
  133. case "*bool":
  134. if _, ok := in.FromValue.(*bool); ok {
  135. return in.FromValue
  136. }
  137. v := Bool(in.FromValue)
  138. return &v
  139. case "string":
  140. return String(in.FromValue)
  141. case "*string":
  142. if _, ok := in.FromValue.(*string); ok {
  143. return in.FromValue
  144. }
  145. v := String(in.FromValue)
  146. return &v
  147. case "[]byte":
  148. return Bytes(in.FromValue)
  149. case "[]int":
  150. return Ints(in.FromValue)
  151. case "[]int32":
  152. return Int32s(in.FromValue)
  153. case "[]int64":
  154. return Int64s(in.FromValue)
  155. case "[]uint":
  156. return Uints(in.FromValue)
  157. case "[]uint8":
  158. return Bytes(in.FromValue)
  159. case "[]uint32":
  160. return Uint32s(in.FromValue)
  161. case "[]uint64":
  162. return Uint64s(in.FromValue)
  163. case "[]float32":
  164. return Float32s(in.FromValue)
  165. case "[]float64":
  166. return Float64s(in.FromValue)
  167. case "[]string":
  168. return Strings(in.FromValue)
  169. case "Time", "time.Time":
  170. if len(in.Extra) > 0 {
  171. return Time(in.FromValue, String(in.Extra[0]))
  172. }
  173. return Time(in.FromValue)
  174. case "*time.Time":
  175. var v interface{}
  176. if len(in.Extra) > 0 {
  177. v = Time(in.FromValue, String(in.Extra[0]))
  178. } else {
  179. if _, ok := in.FromValue.(*time.Time); ok {
  180. return in.FromValue
  181. }
  182. v = Time(in.FromValue)
  183. }
  184. return &v
  185. case "GTime", "gtime.Time":
  186. if len(in.Extra) > 0 {
  187. if v := GTime(in.FromValue, String(in.Extra[0])); v != nil {
  188. return *v
  189. } else {
  190. return *gtime.New()
  191. }
  192. }
  193. if v := GTime(in.FromValue); v != nil {
  194. return *v
  195. } else {
  196. return *gtime.New()
  197. }
  198. case "*gtime.Time":
  199. if len(in.Extra) > 0 {
  200. if v := GTime(in.FromValue, String(in.Extra[0])); v != nil {
  201. return v
  202. } else {
  203. return gtime.New()
  204. }
  205. }
  206. if v := GTime(in.FromValue); v != nil {
  207. return v
  208. } else {
  209. return gtime.New()
  210. }
  211. case "Duration", "time.Duration":
  212. return Duration(in.FromValue)
  213. case "*time.Duration":
  214. if _, ok := in.FromValue.(*time.Duration); ok {
  215. return in.FromValue
  216. }
  217. v := Duration(in.FromValue)
  218. return &v
  219. case "map[string]string":
  220. return MapStrStr(in.FromValue)
  221. case "map[string]interface{}":
  222. return Map(in.FromValue)
  223. case "[]map[string]interface{}":
  224. return Maps(in.FromValue)
  225. case "json.RawMessage":
  226. return Bytes(in.FromValue)
  227. default:
  228. if in.ReferValue != nil {
  229. var referReflectValue reflect.Value
  230. if v, ok := in.ReferValue.(reflect.Value); ok {
  231. referReflectValue = v
  232. } else {
  233. referReflectValue = reflect.ValueOf(in.ReferValue)
  234. }
  235. defer func() {
  236. if recover() != nil {
  237. if err := bindVarToReflectValue(referReflectValue, in.FromValue, nil); err == nil {
  238. in.alreadySetToReferValue = true
  239. convertedValue = referReflectValue.Interface()
  240. }
  241. }
  242. }()
  243. in.ToTypeName = referReflectValue.Kind().String()
  244. in.ReferValue = nil
  245. return reflect.ValueOf(doConvert(in)).Convert(referReflectValue.Type()).Interface()
  246. }
  247. return in.FromValue
  248. }
  249. }
  250. func doConvertWithReflectValueSet(reflectValue reflect.Value, in doConvertInput) {
  251. convertedValue := doConvert(in)
  252. if !in.alreadySetToReferValue {
  253. reflectValue.Set(reflect.ValueOf(convertedValue))
  254. }
  255. }