在Go中轻松安全地从一种数据类型转换为另一种数据类型
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

640 lines
14 KiB

  1. // Copyright © 2014 Steve Francia <spf@spf13.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. package cast
  6. import (
  7. "fmt"
  8. "html/template"
  9. "reflect"
  10. "strconv"
  11. "strings"
  12. "time"
  13. )
  14. // ToTimeE casts an interface to a time.Time type.
  15. func ToTimeE(i interface{}) (tim time.Time, err error) {
  16. i = indirect(i)
  17. switch v := i.(type) {
  18. case time.Time:
  19. return v, nil
  20. case string:
  21. return StringToDate(v)
  22. case int:
  23. return time.Unix(int64(v), 0), nil
  24. case int32:
  25. return time.Unix(int64(v), 0), nil
  26. case int64:
  27. return time.Unix(v, 0), nil
  28. default:
  29. return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
  30. }
  31. }
  32. // ToDurationE casts an interface to a time.Duration type.
  33. func ToDurationE(i interface{}) (d time.Duration, err error) {
  34. i = indirect(i)
  35. switch s := i.(type) {
  36. case time.Duration:
  37. return s, nil
  38. case int64, int32, int16, int8, int:
  39. d = time.Duration(ToInt64(s))
  40. return
  41. case float32, float64:
  42. d = time.Duration(ToFloat64(s))
  43. return
  44. case string:
  45. if strings.ContainsAny(s, "nsuµmh") {
  46. d, err = time.ParseDuration(s)
  47. } else {
  48. d, err = time.ParseDuration(s + "ns")
  49. }
  50. return
  51. default:
  52. err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
  53. return
  54. }
  55. }
  56. // ToBoolE casts an interface to a bool type.
  57. func ToBoolE(i interface{}) (bool, error) {
  58. i = indirect(i)
  59. switch b := i.(type) {
  60. case bool:
  61. return b, nil
  62. case nil:
  63. return false, nil
  64. case int:
  65. if i.(int) != 0 {
  66. return true, nil
  67. }
  68. return false, nil
  69. case string:
  70. return strconv.ParseBool(i.(string))
  71. default:
  72. return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
  73. }
  74. }
  75. // ToFloat64E casts an interface to a float64 type.
  76. func ToFloat64E(i interface{}) (float64, error) {
  77. i = indirect(i)
  78. switch s := i.(type) {
  79. case float64:
  80. return s, nil
  81. case float32:
  82. return float64(s), nil
  83. case int64:
  84. return float64(s), nil
  85. case int32:
  86. return float64(s), nil
  87. case int16:
  88. return float64(s), nil
  89. case int8:
  90. return float64(s), nil
  91. case int:
  92. return float64(s), nil
  93. case string:
  94. v, err := strconv.ParseFloat(s, 64)
  95. if err == nil {
  96. return float64(v), nil
  97. }
  98. return 0.0, fmt.Errorf("unable to cast %#v of type %T to float", i, i)
  99. default:
  100. return 0.0, fmt.Errorf("unable to cast %#v of type %T to float", i, i)
  101. }
  102. }
  103. // ToInt64E casts an interface to an int64 type.
  104. func ToInt64E(i interface{}) (int64, error) {
  105. i = indirect(i)
  106. switch s := i.(type) {
  107. case int64:
  108. return s, nil
  109. case int:
  110. return int64(s), nil
  111. case int32:
  112. return int64(s), nil
  113. case int16:
  114. return int64(s), nil
  115. case int8:
  116. return int64(s), nil
  117. case string:
  118. v, err := strconv.ParseInt(s, 0, 0)
  119. if err == nil {
  120. return v, nil
  121. }
  122. return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
  123. case float64:
  124. return int64(s), nil
  125. case bool:
  126. if bool(s) {
  127. return int64(1), nil
  128. }
  129. return int64(0), nil
  130. case nil:
  131. return int64(0), nil
  132. default:
  133. return int64(0), fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
  134. }
  135. }
  136. // ToInt32E casts an interface to an int32 type.
  137. func ToInt32E(i interface{}) (int32, error) {
  138. i = indirect(i)
  139. switch s := i.(type) {
  140. case int64:
  141. return int32(s), nil
  142. case int:
  143. return int32(s), nil
  144. case int32:
  145. return s, nil
  146. case int16:
  147. return int32(s), nil
  148. case int8:
  149. return int32(s), nil
  150. case string:
  151. v, err := strconv.ParseInt(s, 0, 0)
  152. if err == nil {
  153. return int32(v), nil
  154. }
  155. return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
  156. case float64:
  157. return int32(s), nil
  158. case bool:
  159. if bool(s) {
  160. return int32(1), nil
  161. }
  162. return int32(0), nil
  163. case nil:
  164. return int32(0), nil
  165. default:
  166. return int32(0), fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
  167. }
  168. }
  169. // ToInt16E casts an interface to an int16 type.
  170. func ToInt16E(i interface{}) (int16, error) {
  171. i = indirect(i)
  172. switch s := i.(type) {
  173. case int64:
  174. return int16(s), nil
  175. case int:
  176. return int16(s), nil
  177. case int32:
  178. return int16(s), nil
  179. case int16:
  180. return s, nil
  181. case int8:
  182. return int16(s), nil
  183. case string:
  184. v, err := strconv.ParseInt(s, 0, 0)
  185. if err == nil {
  186. return int16(v), nil
  187. }
  188. return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
  189. case float64:
  190. return int16(s), nil
  191. case bool:
  192. if bool(s) {
  193. return int16(1), nil
  194. }
  195. return int16(0), nil
  196. case nil:
  197. return int16(0), nil
  198. default:
  199. return int16(0), fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
  200. }
  201. }
  202. // ToInt8E casts an interface to an int8 type.
  203. func ToInt8E(i interface{}) (int8, error) {
  204. i = indirect(i)
  205. switch s := i.(type) {
  206. case int64:
  207. return int8(s), nil
  208. case int:
  209. return int8(s), nil
  210. case int32:
  211. return int8(s), nil
  212. case int16:
  213. return int8(s), nil
  214. case int8:
  215. return s, nil
  216. case string:
  217. v, err := strconv.ParseInt(s, 0, 0)
  218. if err == nil {
  219. return int8(v), nil
  220. }
  221. return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
  222. case float64:
  223. return int8(s), nil
  224. case bool:
  225. if bool(s) {
  226. return int8(1), nil
  227. }
  228. return int8(0), nil
  229. case nil:
  230. return int8(0), nil
  231. default:
  232. return int8(0), fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
  233. }
  234. }
  235. // ToIntE casts an interface to an int type.
  236. func ToIntE(i interface{}) (int, error) {
  237. i = indirect(i)
  238. switch s := i.(type) {
  239. case int:
  240. return s, nil
  241. case int64:
  242. return int(s), nil
  243. case int32:
  244. return int(s), nil
  245. case int16:
  246. return int(s), nil
  247. case int8:
  248. return int(s), nil
  249. case string:
  250. v, err := strconv.ParseInt(s, 0, 0)
  251. if err == nil {
  252. return int(v), nil
  253. }
  254. return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
  255. case float64:
  256. return int(s), nil
  257. case bool:
  258. if bool(s) {
  259. return 1, nil
  260. }
  261. return 0, nil
  262. case nil:
  263. return 0, nil
  264. default:
  265. return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
  266. }
  267. }
  268. // From html/template/content.go
  269. // Copyright 2011 The Go Authors. All rights reserved.
  270. // indirect returns the value, after dereferencing as many times
  271. // as necessary to reach the base type (or nil).
  272. func indirect(a interface{}) interface{} {
  273. if a == nil {
  274. return nil
  275. }
  276. if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
  277. // Avoid creating a reflect.Value if it's not a pointer.
  278. return a
  279. }
  280. v := reflect.ValueOf(a)
  281. for v.Kind() == reflect.Ptr && !v.IsNil() {
  282. v = v.Elem()
  283. }
  284. return v.Interface()
  285. }
  286. // From html/template/content.go
  287. // Copyright 2011 The Go Authors. All rights reserved.
  288. // indirectToStringerOrError returns the value, after dereferencing as many times
  289. // as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
  290. // or error,
  291. func indirectToStringerOrError(a interface{}) interface{} {
  292. if a == nil {
  293. return nil
  294. }
  295. var errorType = reflect.TypeOf((*error)(nil)).Elem()
  296. var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
  297. v := reflect.ValueOf(a)
  298. for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
  299. v = v.Elem()
  300. }
  301. return v.Interface()
  302. }
  303. // ToStringE casts an interface to a string type.
  304. func ToStringE(i interface{}) (string, error) {
  305. i = indirectToStringerOrError(i)
  306. switch s := i.(type) {
  307. case string:
  308. return s, nil
  309. case bool:
  310. return strconv.FormatBool(s), nil
  311. case float64:
  312. return strconv.FormatFloat(s, 'f', -1, 64), nil
  313. case int64:
  314. return strconv.FormatInt(s, 10), nil
  315. case int:
  316. return strconv.Itoa(s), nil
  317. case []byte:
  318. return string(s), nil
  319. case template.HTML:
  320. return string(s), nil
  321. case template.URL:
  322. return string(s), nil
  323. case template.JS:
  324. return string(s), nil
  325. case template.CSS:
  326. return string(s), nil
  327. case template.HTMLAttr:
  328. return string(s), nil
  329. case nil:
  330. return "", nil
  331. case fmt.Stringer:
  332. return s.String(), nil
  333. case error:
  334. return s.Error(), nil
  335. default:
  336. return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
  337. }
  338. }
  339. // ToStringMapStringE casts an interface to a map[string]string type.
  340. func ToStringMapStringE(i interface{}) (map[string]string, error) {
  341. var m = map[string]string{}
  342. switch v := i.(type) {
  343. case map[string]string:
  344. return v, nil
  345. case map[string]interface{}:
  346. for k, val := range v {
  347. m[ToString(k)] = ToString(val)
  348. }
  349. return m, nil
  350. case map[interface{}]string:
  351. for k, val := range v {
  352. m[ToString(k)] = ToString(val)
  353. }
  354. return m, nil
  355. case map[interface{}]interface{}:
  356. for k, val := range v {
  357. m[ToString(k)] = ToString(val)
  358. }
  359. return m, nil
  360. default:
  361. return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
  362. }
  363. }
  364. // ToStringMapStringSliceE casts an interface to a map[string][]string type.
  365. func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
  366. var m = map[string][]string{}
  367. switch v := i.(type) {
  368. case map[string][]string:
  369. return v, nil
  370. case map[string][]interface{}:
  371. for k, val := range v {
  372. m[ToString(k)] = ToStringSlice(val)
  373. }
  374. return m, nil
  375. case map[string]string:
  376. for k, val := range v {
  377. m[ToString(k)] = []string{val}
  378. }
  379. case map[string]interface{}:
  380. for k, val := range v {
  381. switch vt := val.(type) {
  382. case []interface{}:
  383. m[ToString(k)] = ToStringSlice(vt)
  384. case []string:
  385. m[ToString(k)] = vt
  386. default:
  387. m[ToString(k)] = []string{ToString(val)}
  388. }
  389. }
  390. return m, nil
  391. case map[interface{}][]string:
  392. for k, val := range v {
  393. m[ToString(k)] = ToStringSlice(val)
  394. }
  395. return m, nil
  396. case map[interface{}]string:
  397. for k, val := range v {
  398. m[ToString(k)] = ToStringSlice(val)
  399. }
  400. return m, nil
  401. case map[interface{}][]interface{}:
  402. for k, val := range v {
  403. m[ToString(k)] = ToStringSlice(val)
  404. }
  405. return m, nil
  406. case map[interface{}]interface{}:
  407. for k, val := range v {
  408. key, err := ToStringE(k)
  409. if err != nil {
  410. return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
  411. }
  412. value, err := ToStringSliceE(val)
  413. if err != nil {
  414. return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
  415. }
  416. m[key] = value
  417. }
  418. default:
  419. return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
  420. }
  421. return m, nil
  422. }
  423. // ToStringMapBoolE casts an interface to a map[string]bool type.
  424. func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
  425. var m = map[string]bool{}
  426. switch v := i.(type) {
  427. case map[interface{}]interface{}:
  428. for k, val := range v {
  429. m[ToString(k)] = ToBool(val)
  430. }
  431. return m, nil
  432. case map[string]interface{}:
  433. for k, val := range v {
  434. m[ToString(k)] = ToBool(val)
  435. }
  436. return m, nil
  437. case map[string]bool:
  438. return v, nil
  439. default:
  440. return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
  441. }
  442. }
  443. // ToStringMapE casts an interface to a map[string]interface{} type.
  444. func ToStringMapE(i interface{}) (map[string]interface{}, error) {
  445. var m = map[string]interface{}{}
  446. switch v := i.(type) {
  447. case map[interface{}]interface{}:
  448. for k, val := range v {
  449. m[ToString(k)] = val
  450. }
  451. return m, nil
  452. case map[string]interface{}:
  453. return v, nil
  454. default:
  455. return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
  456. }
  457. }
  458. // ToSliceE casts an interface to a []interface{} type.
  459. func ToSliceE(i interface{}) ([]interface{}, error) {
  460. var s []interface{}
  461. switch v := i.(type) {
  462. case []interface{}:
  463. return append(s, v...), nil
  464. case []map[string]interface{}:
  465. for _, u := range v {
  466. s = append(s, u)
  467. }
  468. return s, nil
  469. default:
  470. return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
  471. }
  472. }
  473. // ToBoolSliceE casts an interface to a []bool type.
  474. func ToBoolSliceE(i interface{}) ([]bool, error) {
  475. if i == nil {
  476. return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
  477. }
  478. switch v := i.(type) {
  479. case []bool:
  480. return v, nil
  481. }
  482. kind := reflect.TypeOf(i).Kind()
  483. switch kind {
  484. case reflect.Slice, reflect.Array:
  485. s := reflect.ValueOf(i)
  486. a := make([]bool, s.Len())
  487. for j := 0; j < s.Len(); j++ {
  488. val, err := ToBoolE(s.Index(j).Interface())
  489. if err != nil {
  490. return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
  491. }
  492. a[j] = val
  493. }
  494. return a, nil
  495. default:
  496. return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
  497. }
  498. }
  499. // ToStringSliceE casts an interface to a []string type.
  500. func ToStringSliceE(i interface{}) ([]string, error) {
  501. var a []string
  502. switch v := i.(type) {
  503. case []interface{}:
  504. for _, u := range v {
  505. a = append(a, ToString(u))
  506. }
  507. return a, nil
  508. case []string:
  509. return v, nil
  510. case string:
  511. return strings.Fields(v), nil
  512. case interface{}:
  513. str, err := ToStringE(v)
  514. if err != nil {
  515. return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
  516. }
  517. return []string{str}, nil
  518. default:
  519. return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
  520. }
  521. }
  522. // ToIntSliceE casts an interface to a []int type.
  523. func ToIntSliceE(i interface{}) ([]int, error) {
  524. if i == nil {
  525. return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
  526. }
  527. switch v := i.(type) {
  528. case []int:
  529. return v, nil
  530. }
  531. kind := reflect.TypeOf(i).Kind()
  532. switch kind {
  533. case reflect.Slice, reflect.Array:
  534. s := reflect.ValueOf(i)
  535. a := make([]int, s.Len())
  536. for j := 0; j < s.Len(); j++ {
  537. val, err := ToIntE(s.Index(j).Interface())
  538. if err != nil {
  539. return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
  540. }
  541. a[j] = val
  542. }
  543. return a, nil
  544. default:
  545. return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
  546. }
  547. }
  548. // StringToDate attempts to parse a string into a time.Time type using a
  549. // predefined list of formats. If no suitable format is found, an error is
  550. // returned.
  551. func StringToDate(s string) (time.Time, error) {
  552. return parseDateWith(s, []string{
  553. time.RFC3339,
  554. "2006-01-02T15:04:05", // iso8601 without timezone
  555. time.RFC1123Z,
  556. time.RFC1123,
  557. time.RFC822Z,
  558. time.RFC822,
  559. time.RFC850,
  560. time.ANSIC,
  561. time.UnixDate,
  562. time.RubyDate,
  563. "2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
  564. "2006-01-02",
  565. "02 Jan 2006",
  566. "2006-01-02 15:04:05 -07:00",
  567. "2006-01-02 15:04:05 -0700",
  568. "2006-01-02 15:04:05Z07:00", // RFC3339 without T
  569. "2006-01-02 15:04:05",
  570. time.Kitchen,
  571. time.Stamp,
  572. time.StampMilli,
  573. time.StampMicro,
  574. time.StampNano,
  575. })
  576. }
  577. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  578. for _, dateType := range dates {
  579. if d, e = time.Parse(dateType, s); e == nil {
  580. return
  581. }
  582. }
  583. return d, fmt.Errorf("unable to parse date: %s", s)
  584. }