在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.
 
 
 

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