在Go中轻松安全地从一种数据类型转换为另一种数据类型
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

285 satır
6.1 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. "errors"
  8. "fmt"
  9. "html/template"
  10. "reflect"
  11. "strconv"
  12. "time"
  13. jww "github.com/spf13/jwalterweatherman"
  14. )
  15. func ToTimeE(i interface{}) (tim time.Time, err error) {
  16. jww.DEBUG.Println("ToTimeE called on type:", reflect.TypeOf(i))
  17. switch s := i.(type) {
  18. case time.Time:
  19. return s, nil
  20. case string:
  21. d, e := StringToDate(s)
  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. default:
  27. return time.Time{}, fmt.Errorf("Unable to Cast %#v to Time\n", i)
  28. }
  29. }
  30. func ToBoolE(i interface{}) (bool, error) {
  31. jww.DEBUG.Println("ToBoolE called on type:", reflect.TypeOf(i))
  32. switch b := i.(type) {
  33. case bool:
  34. return b, nil
  35. case nil:
  36. return false, nil
  37. case int:
  38. if i.(int) != 0 {
  39. return true, nil
  40. }
  41. return false, nil
  42. case string:
  43. return strconv.ParseBool(i.(string))
  44. default:
  45. return false, fmt.Errorf("Unable to Cast %#v to bool", i)
  46. }
  47. }
  48. func ToFloat64E(i interface{}) (float64, error) {
  49. jww.DEBUG.Println("ToFloat64E called on type:", reflect.TypeOf(i))
  50. switch s := i.(type) {
  51. case float64:
  52. return s, nil
  53. case float32:
  54. return float64(s), nil
  55. case int64:
  56. return float64(s), nil
  57. case int32:
  58. return float64(s), nil
  59. case int16:
  60. return float64(s), nil
  61. case int8:
  62. return float64(s), nil
  63. case int:
  64. return float64(s), nil
  65. case string:
  66. v, err := strconv.ParseFloat(s, 64)
  67. if err == nil {
  68. return float64(v), nil
  69. } else {
  70. return 0.0, fmt.Errorf("Unable to Cast %#v to float", i)
  71. }
  72. default:
  73. return 0.0, fmt.Errorf("Unable to Cast %#v to float", i)
  74. }
  75. }
  76. func ToIntE(i interface{}) (int, error) {
  77. jww.DEBUG.Println("ToIntE called on type:", reflect.TypeOf(i))
  78. switch s := i.(type) {
  79. case int:
  80. return s, nil
  81. case int64:
  82. return int(s), nil
  83. case int32:
  84. return int(s), nil
  85. case int16:
  86. return int(s), nil
  87. case int8:
  88. return int(s), nil
  89. case string:
  90. v, err := strconv.ParseInt(s, 0, 0)
  91. if err == nil {
  92. return int(v), nil
  93. } else {
  94. return 0, fmt.Errorf("Unable to Cast %#v to int", i)
  95. }
  96. case float64:
  97. return int(s), nil
  98. case bool:
  99. if bool(s) {
  100. return 1, nil
  101. } else {
  102. return 0, nil
  103. }
  104. case nil:
  105. return 0, nil
  106. default:
  107. return 0, fmt.Errorf("Unable to Cast %#v to int", i)
  108. }
  109. }
  110. func ToStringE(i interface{}) (string, error) {
  111. jww.DEBUG.Println("ToStringE called on type:", reflect.TypeOf(i))
  112. switch s := i.(type) {
  113. case string:
  114. return s, nil
  115. case float64:
  116. return strconv.FormatFloat(i.(float64), 'f', -1, 64), nil
  117. case int:
  118. return strconv.FormatInt(int64(i.(int)), 10), nil
  119. case []byte:
  120. return string(s), nil
  121. case template.HTML:
  122. return string(s), nil
  123. case nil:
  124. return "", nil
  125. case fmt.Stringer:
  126. return s.String(), nil
  127. case error:
  128. return s.Error(), nil
  129. default:
  130. return "", fmt.Errorf("Unable to Cast %#v to string", i)
  131. }
  132. }
  133. func ToStringMapStringE(i interface{}) (map[string]string, error) {
  134. jww.DEBUG.Println("ToStringMapStringE called on type:", reflect.TypeOf(i))
  135. var m = map[string]string{}
  136. switch v := i.(type) {
  137. case map[interface{}]interface{}:
  138. for k, val := range v {
  139. m[ToString(k)] = ToString(val)
  140. }
  141. return m, nil
  142. case map[string]interface{}:
  143. for k, val := range v {
  144. m[ToString(k)] = ToString(val)
  145. }
  146. return m, nil
  147. case map[string]string:
  148. return v, nil
  149. default:
  150. return m, fmt.Errorf("Unable to Cast %#v to map[string]string", i)
  151. }
  152. return m, fmt.Errorf("Unable to Cast %#v to map[string]string", i)
  153. }
  154. func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
  155. jww.DEBUG.Println("ToStringMapBoolE called on type:", reflect.TypeOf(i))
  156. var m = map[string]bool{}
  157. switch v := i.(type) {
  158. case map[interface{}]interface{}:
  159. for k, val := range v {
  160. m[ToString(k)] = ToBool(val)
  161. }
  162. return m, nil
  163. case map[string]interface{}:
  164. for k, val := range v {
  165. m[ToString(k)] = ToBool(val)
  166. }
  167. return m, nil
  168. case map[string]bool:
  169. return v, nil
  170. default:
  171. return m, fmt.Errorf("Unable to Cast %#v to map[string]bool", i)
  172. }
  173. return m, fmt.Errorf("Unable to Cast %#v to map[string]bool", i)
  174. }
  175. func ToStringMapE(i interface{}) (map[string]interface{}, error) {
  176. jww.DEBUG.Println("ToStringMapE called on type:", reflect.TypeOf(i))
  177. var m = map[string]interface{}{}
  178. switch v := i.(type) {
  179. case map[interface{}]interface{}:
  180. for k, val := range v {
  181. m[ToString(k)] = val
  182. }
  183. return m, nil
  184. case map[string]interface{}:
  185. return v, nil
  186. default:
  187. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  188. }
  189. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  190. }
  191. func ToSliceE(i interface{}) ([]interface{}, error) {
  192. jww.DEBUG.Println("ToSliceE called on type:", reflect.TypeOf(i))
  193. var s []interface{}
  194. switch v := i.(type) {
  195. case []interface{}:
  196. for _, u := range v {
  197. s = append(s, u)
  198. }
  199. return s, nil
  200. case []map[string]interface{}:
  201. for _, u := range v {
  202. s = append(s, u)
  203. }
  204. return s, nil
  205. default:
  206. return s, fmt.Errorf("Unable to Cast %#v of type %v to []interface{}", i, reflect.TypeOf(i))
  207. }
  208. return s, fmt.Errorf("Unable to Cast %#v to []interface{}", i)
  209. }
  210. func ToStringSliceE(i interface{}) ([]string, error) {
  211. jww.DEBUG.Println("ToStringSliceE called on type:", reflect.TypeOf(i))
  212. var a []string
  213. switch v := i.(type) {
  214. case []interface{}:
  215. for _, u := range v {
  216. a = append(a, ToString(u))
  217. }
  218. return a, nil
  219. case []string:
  220. return v, nil
  221. default:
  222. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  223. }
  224. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  225. }
  226. func StringToDate(s string) (time.Time, error) {
  227. return parseDateWith(s, []string{
  228. time.RFC3339,
  229. "2006-01-02T15:04:05", // iso8601 without timezone
  230. time.RFC1123Z,
  231. time.RFC1123,
  232. time.RFC822Z,
  233. time.RFC822,
  234. time.ANSIC,
  235. time.UnixDate,
  236. time.RubyDate,
  237. "2006-01-02 15:04:05Z07:00",
  238. "02 Jan 06 15:04 MST",
  239. "2006-01-02",
  240. "02 Jan 2006",
  241. })
  242. }
  243. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  244. for _, dateType := range dates {
  245. if d, e = time.Parse(dateType, s); e == nil {
  246. return
  247. }
  248. }
  249. return d, errors.New(fmt.Sprintf("Unable to parse date: %s", s))
  250. }