cast.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. package common
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "html/template"
  6. "reflect"
  7. "strconv"
  8. "sync"
  9. )
  10. type Strictness int8
  11. const (
  12. STRICT Strictness = iota
  13. CONVERT_SAMEKIND
  14. CONVERT_ALL
  15. )
  16. /*********** Type Cast Utilities *****/
  17. //TODO datetime type
  18. func ToStringAlways(input interface{}) string {
  19. return fmt.Sprintf("%v", input)
  20. }
  21. func ToString(input interface{}, sn Strictness) (string, error) {
  22. switch s := input.(type) {
  23. case string:
  24. return s, nil
  25. case []byte:
  26. return string(s), nil
  27. default:
  28. if sn == CONVERT_ALL {
  29. switch s := input.(type) {
  30. case string:
  31. return s, nil
  32. case bool:
  33. return strconv.FormatBool(s), nil
  34. case float64:
  35. return strconv.FormatFloat(s, 'f', -1, 64), nil
  36. case float32:
  37. return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
  38. case int:
  39. return strconv.Itoa(s), nil
  40. case int64:
  41. return strconv.FormatInt(s, 10), nil
  42. case int32:
  43. return strconv.Itoa(int(s)), nil
  44. case int16:
  45. return strconv.FormatInt(int64(s), 10), nil
  46. case int8:
  47. return strconv.FormatInt(int64(s), 10), nil
  48. case uint:
  49. return strconv.FormatUint(uint64(s), 10), nil
  50. case uint64:
  51. return strconv.FormatUint(s, 10), nil
  52. case uint32:
  53. return strconv.FormatUint(uint64(s), 10), nil
  54. case uint16:
  55. return strconv.FormatUint(uint64(s), 10), nil
  56. case uint8:
  57. return strconv.FormatUint(uint64(s), 10), nil
  58. case template.HTML:
  59. return string(s), nil
  60. case template.URL:
  61. return string(s), nil
  62. case template.JS:
  63. return string(s), nil
  64. case template.CSS:
  65. return string(s), nil
  66. case template.HTMLAttr:
  67. return string(s), nil
  68. case nil:
  69. return "", nil
  70. case fmt.Stringer:
  71. return s.String(), nil
  72. case error:
  73. return s.Error(), nil
  74. }
  75. }
  76. }
  77. return "", fmt.Errorf("cannot convert %[1]T(%[1]v) to string", input)
  78. }
  79. func ToInt(input interface{}, sn Strictness) (int, error) {
  80. switch s := input.(type) {
  81. case int:
  82. return s, nil
  83. case int64:
  84. return int(s), nil
  85. case int32:
  86. return int(s), nil
  87. case int16:
  88. return int(s), nil
  89. case int8:
  90. return int(s), nil
  91. case uint:
  92. return int(s), nil
  93. case uint64:
  94. return int(s), nil
  95. case uint32:
  96. return int(s), nil
  97. case uint16:
  98. return int(s), nil
  99. case uint8:
  100. return int(s), nil
  101. case float64:
  102. if sn != STRICT || isIntegral64(s) {
  103. return int(s), nil
  104. }
  105. case float32:
  106. if sn != STRICT || isIntegral32(s) {
  107. return int(s), nil
  108. }
  109. case string:
  110. if sn == CONVERT_ALL {
  111. v, err := strconv.ParseInt(s, 0, 0)
  112. if err == nil {
  113. return int(v), nil
  114. }
  115. }
  116. case bool:
  117. if sn == CONVERT_ALL {
  118. if s {
  119. return 1, nil
  120. }
  121. return 0, nil
  122. }
  123. case nil:
  124. if sn == CONVERT_ALL {
  125. return 0, nil
  126. }
  127. }
  128. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to int", input)
  129. }
  130. func ToInt64(input interface{}, sn Strictness) (int64, error) {
  131. switch s := input.(type) {
  132. case int:
  133. return int64(s), nil
  134. case int64:
  135. return s, nil
  136. case int32:
  137. return int64(s), nil
  138. case int16:
  139. return int64(s), nil
  140. case int8:
  141. return int64(s), nil
  142. case uint:
  143. return int64(s), nil
  144. case uint64:
  145. return int64(s), nil
  146. case uint32:
  147. return int64(s), nil
  148. case uint16:
  149. return int64(s), nil
  150. case uint8:
  151. return int64(s), nil
  152. case float64:
  153. if sn != STRICT || isIntegral64(s) {
  154. return int64(s), nil
  155. }
  156. case float32:
  157. if sn != STRICT || isIntegral32(s) {
  158. return int64(s), nil
  159. }
  160. case string:
  161. if sn == CONVERT_ALL {
  162. v, err := strconv.ParseInt(s, 0, 0)
  163. if err == nil {
  164. return int64(v), nil
  165. }
  166. }
  167. case bool:
  168. if sn == CONVERT_ALL {
  169. if s {
  170. return 1, nil
  171. }
  172. return 0, nil
  173. }
  174. case nil:
  175. if sn == CONVERT_ALL {
  176. return 0, nil
  177. }
  178. }
  179. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to int64", input)
  180. }
  181. func ToFloat64(input interface{}, sn Strictness) (float64, error) {
  182. switch s := input.(type) {
  183. case float64:
  184. return s, nil
  185. case float32:
  186. return float64(s), nil
  187. case int:
  188. if sn != STRICT {
  189. return float64(s), nil
  190. }
  191. case int64:
  192. if sn != STRICT {
  193. return float64(s), nil
  194. }
  195. case int32:
  196. if sn != STRICT {
  197. return float64(s), nil
  198. }
  199. case int16:
  200. if sn != STRICT {
  201. return float64(s), nil
  202. }
  203. case int8:
  204. if sn != STRICT {
  205. return float64(s), nil
  206. }
  207. case uint:
  208. if sn != STRICT {
  209. return float64(s), nil
  210. }
  211. case uint64:
  212. if sn != STRICT {
  213. return float64(s), nil
  214. }
  215. case uint32:
  216. if sn != STRICT {
  217. return float64(s), nil
  218. }
  219. case uint16:
  220. if sn != STRICT {
  221. return float64(s), nil
  222. }
  223. case uint8:
  224. if sn != STRICT {
  225. return float64(s), nil
  226. }
  227. case string:
  228. if sn == CONVERT_ALL {
  229. v, err := strconv.ParseFloat(s, 64)
  230. if err == nil {
  231. return v, nil
  232. }
  233. }
  234. case bool:
  235. if sn == CONVERT_ALL {
  236. if s {
  237. return 1, nil
  238. }
  239. return 0, nil
  240. }
  241. }
  242. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to float64", input)
  243. }
  244. func ToUint64(i interface{}, sn Strictness) (uint64, error) {
  245. switch s := i.(type) {
  246. case string:
  247. if sn == CONVERT_ALL {
  248. v, err := strconv.ParseUint(s, 0, 64)
  249. if err == nil {
  250. return v, nil
  251. }
  252. }
  253. case int:
  254. if s < 0 {
  255. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
  256. }
  257. return uint64(s), nil
  258. case int64:
  259. if s < 0 {
  260. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
  261. }
  262. return uint64(s), nil
  263. case int32:
  264. if s < 0 {
  265. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
  266. }
  267. return uint64(s), nil
  268. case int16:
  269. if s < 0 {
  270. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
  271. }
  272. return uint64(s), nil
  273. case int8:
  274. if s < 0 {
  275. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
  276. }
  277. return uint64(s), nil
  278. case uint:
  279. return uint64(s), nil
  280. case uint64:
  281. return s, nil
  282. case uint32:
  283. return uint64(s), nil
  284. case uint16:
  285. return uint64(s), nil
  286. case uint8:
  287. return uint64(s), nil
  288. case float32:
  289. if s < 0 {
  290. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
  291. }
  292. if sn != STRICT || isIntegral32(s) {
  293. return uint64(s), nil
  294. }
  295. case float64:
  296. if s < 0 {
  297. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
  298. }
  299. if sn != STRICT || isIntegral64(s) {
  300. return uint64(s), nil
  301. }
  302. case bool:
  303. if sn == CONVERT_ALL {
  304. if s {
  305. return 1, nil
  306. }
  307. return 0, nil
  308. }
  309. case nil:
  310. if sn == CONVERT_ALL {
  311. return 0, nil
  312. }
  313. }
  314. return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint", i)
  315. }
  316. func ToBool(input interface{}, sn Strictness) (bool, error) {
  317. switch b := input.(type) {
  318. case bool:
  319. return b, nil
  320. case nil:
  321. if sn == CONVERT_ALL {
  322. return false, nil
  323. }
  324. case int:
  325. if sn == CONVERT_ALL {
  326. if b != 0 {
  327. return true, nil
  328. }
  329. return false, nil
  330. }
  331. case string:
  332. if sn == CONVERT_ALL {
  333. return strconv.ParseBool(b)
  334. }
  335. }
  336. return false, fmt.Errorf("cannot convert %[1]T(%[1]v) to bool", input)
  337. }
  338. func ToBytes(input interface{}, sn Strictness) ([]byte, error) {
  339. switch b := input.(type) {
  340. case []byte:
  341. return b, nil
  342. case string:
  343. if sn != STRICT {
  344. return []byte(b), nil
  345. }
  346. }
  347. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bytes", input)
  348. }
  349. func ToStringMap(input interface{}) (map[string]interface{}, error) {
  350. var m = map[string]interface{}{}
  351. switch v := input.(type) {
  352. case map[interface{}]interface{}:
  353. for k, val := range v {
  354. m[ToStringAlways(k)] = val
  355. }
  356. return m, nil
  357. case map[string]interface{}:
  358. return v, nil
  359. //case string:
  360. // err := jsonStringToObject(v, &m)
  361. // return m, err
  362. default:
  363. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to map", input)
  364. }
  365. }
  366. func ToTypedSlice(input interface{}, conv func(interface{}, Strictness) (interface{}, error), eleType string, sn Strictness) (interface{}, error) {
  367. s := reflect.ValueOf(input)
  368. if s.Kind() != reflect.Slice {
  369. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to %s slice)", input, eleType)
  370. }
  371. ele, err := conv(s.Index(0).Interface(), sn)
  372. if err != nil {
  373. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to %s slice for the %d element: %v", input, eleType, 0, err)
  374. }
  375. result := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(ele)), s.Len(), s.Len())
  376. result.Index(0).Set(reflect.ValueOf(ele))
  377. for i := 1; i < s.Len(); i++ {
  378. ele, err := conv(s.Index(i).Interface(), sn)
  379. if err != nil {
  380. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to int slice for the %d element: %v", input, i, err)
  381. }
  382. result.Index(i).Set(reflect.ValueOf(ele))
  383. }
  384. return result.Interface(), nil
  385. }
  386. func ToInt64Slice(input interface{}, sn Strictness) ([]int64, error) {
  387. s := reflect.ValueOf(input)
  388. if s.Kind() != reflect.Slice {
  389. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to int slice)", input)
  390. }
  391. var result []int64
  392. for i := 0; i < s.Len(); i++ {
  393. ele, err := ToInt64(s.Index(i).Interface(), sn)
  394. if err != nil {
  395. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to int slice for the %d element: %v", input, i, err)
  396. }
  397. result = append(result, ele)
  398. }
  399. return result, nil
  400. }
  401. func ToUint64Slice(input interface{}, sn Strictness) ([]uint64, error) {
  402. s := reflect.ValueOf(input)
  403. if s.Kind() != reflect.Slice {
  404. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint slice)", input)
  405. }
  406. var result []uint64
  407. for i := 0; i < s.Len(); i++ {
  408. ele, err := ToUint64(s.Index(i).Interface(), sn)
  409. if err != nil {
  410. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint slice for the %d element: %v", input, i, err)
  411. }
  412. result = append(result, ele)
  413. }
  414. return result, nil
  415. }
  416. func ToFloat64Slice(input interface{}, sn Strictness) ([]float64, error) {
  417. s := reflect.ValueOf(input)
  418. if s.Kind() != reflect.Slice {
  419. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to float slice)", input)
  420. }
  421. var result []float64
  422. for i := 0; i < s.Len(); i++ {
  423. ele, err := ToFloat64(s.Index(i).Interface(), sn)
  424. if err != nil {
  425. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to float slice for the %d element: %v", input, i, err)
  426. }
  427. result = append(result, ele)
  428. }
  429. return result, nil
  430. }
  431. func ToBoolSlice(input interface{}, sn Strictness) ([]bool, error) {
  432. s := reflect.ValueOf(input)
  433. if s.Kind() != reflect.Slice {
  434. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bool slice)", input)
  435. }
  436. var result []bool
  437. for i := 0; i < s.Len(); i++ {
  438. ele, err := ToBool(s.Index(i).Interface(), sn)
  439. if err != nil {
  440. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bool slice for the %d element: %v", input, i, err)
  441. }
  442. result = append(result, ele)
  443. }
  444. return result, nil
  445. }
  446. func ToStringSlice(input interface{}, sn Strictness) ([]string, error) {
  447. s := reflect.ValueOf(input)
  448. if s.Kind() != reflect.Slice {
  449. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to string slice)", input)
  450. }
  451. var result []string
  452. for i := 0; i < s.Len(); i++ {
  453. ele, err := ToString(s.Index(i).Interface(), sn)
  454. if err != nil {
  455. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to string slice for the %d element: %v", input, i, err)
  456. }
  457. result = append(result, ele)
  458. }
  459. return result, nil
  460. }
  461. func ToBytesSlice(input interface{}, sn Strictness) ([][]byte, error) {
  462. s := reflect.ValueOf(input)
  463. if s.Kind() != reflect.Slice {
  464. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to string slice)", input)
  465. }
  466. var result [][]byte
  467. for i := 0; i < s.Len(); i++ {
  468. ele, err := ToBytes(s.Index(i).Interface(), sn)
  469. if err != nil {
  470. return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bytes slice for the %d element: %v", input, i, err)
  471. }
  472. result = append(result, ele)
  473. }
  474. return result, nil
  475. }
  476. /*
  477. * Convert a map into a struct. The output parameter must be a pointer to a struct
  478. * The struct can have the json meta data
  479. */
  480. func MapToStruct(input, output interface{}) error {
  481. // convert map to json
  482. jsonString, err := json.Marshal(input)
  483. if err != nil {
  484. return err
  485. }
  486. // convert json to struct
  487. return json.Unmarshal(jsonString, output)
  488. }
  489. func ConvertMap(s map[interface{}]interface{}) map[string]interface{} {
  490. r := make(map[string]interface{})
  491. for k, v := range s {
  492. switch t := v.(type) {
  493. case map[interface{}]interface{}:
  494. v = ConvertMap(t)
  495. case []interface{}:
  496. v = ConvertArray(t)
  497. }
  498. r[fmt.Sprintf("%v", k)] = v
  499. }
  500. return r
  501. }
  502. func ConvertArray(s []interface{}) []interface{} {
  503. r := make([]interface{}, len(s))
  504. for i, e := range s {
  505. switch t := e.(type) {
  506. case map[interface{}]interface{}:
  507. e = ConvertMap(t)
  508. case []interface{}:
  509. e = ConvertArray(t)
  510. }
  511. r[i] = e
  512. }
  513. return r
  514. }
  515. func SyncMapToMap(sm *sync.Map) map[string]interface{} {
  516. m := make(map[string]interface{})
  517. sm.Range(func(k interface{}, v interface{}) bool {
  518. m[fmt.Sprintf("%v", k)] = v
  519. return true
  520. })
  521. return m
  522. }
  523. func MapToSyncMap(m map[string]interface{}) *sync.Map {
  524. sm := new(sync.Map)
  525. for k, v := range m {
  526. sm.Store(k, v)
  527. }
  528. return sm
  529. }
  530. func isIntegral64(val float64) bool {
  531. return val == float64(int(val))
  532. }
  533. func isIntegral32(val float32) bool {
  534. return val == float32(int(val))
  535. }