在Go中轻松安全地从一种数据类型转换为另一种数据类型
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

280 líneas
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. default:
  126. return "", fmt.Errorf("Unable to Cast %#v to string", i)
  127. }
  128. }
  129. func ToStringMapStringE(i interface{}) (map[string]string, error) {
  130. jww.DEBUG.Println("ToStringMapStringE called on type:", reflect.TypeOf(i))
  131. var m = map[string]string{}
  132. switch v := i.(type) {
  133. case map[interface{}]interface{}:
  134. for k, val := range v {
  135. m[ToString(k)] = ToString(val)
  136. }
  137. return m, nil
  138. case map[string]interface{}:
  139. for k, val := range v {
  140. m[ToString(k)] = ToString(val)
  141. }
  142. return m, nil
  143. case map[string]string:
  144. return v, nil
  145. default:
  146. return m, fmt.Errorf("Unable to Cast %#v to map[string]string", i)
  147. }
  148. return m, fmt.Errorf("Unable to Cast %#v to map[string]string", i)
  149. }
  150. func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
  151. jww.DEBUG.Println("ToStringMapBoolE called on type:", reflect.TypeOf(i))
  152. var m = map[string]bool{}
  153. switch v := i.(type) {
  154. case map[interface{}]interface{}:
  155. for k, val := range v {
  156. m[ToString(k)] = ToBool(val)
  157. }
  158. return m, nil
  159. case map[string]interface{}:
  160. for k, val := range v {
  161. m[ToString(k)] = ToBool(val)
  162. }
  163. return m, nil
  164. case map[string]bool:
  165. return v, nil
  166. default:
  167. return m, fmt.Errorf("Unable to Cast %#v to map[string]bool", i)
  168. }
  169. return m, fmt.Errorf("Unable to Cast %#v to map[string]bool", i)
  170. }
  171. func ToStringMapE(i interface{}) (map[string]interface{}, error) {
  172. jww.DEBUG.Println("ToStringMapE called on type:", reflect.TypeOf(i))
  173. var m = map[string]interface{}{}
  174. switch v := i.(type) {
  175. case map[interface{}]interface{}:
  176. for k, val := range v {
  177. m[ToString(k)] = val
  178. }
  179. return m, nil
  180. case map[string]interface{}:
  181. return v, nil
  182. default:
  183. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  184. }
  185. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  186. }
  187. func ToSliceE(i interface{}) ([]interface{}, error) {
  188. jww.DEBUG.Println("ToSliceE called on type:", reflect.TypeOf(i))
  189. var s []interface{}
  190. switch v := i.(type) {
  191. case []interface{}:
  192. for _, u := range v {
  193. s = append(s, u)
  194. }
  195. return s, nil
  196. case []map[string]interface{}:
  197. for _, u := range v {
  198. s = append(s, u)
  199. }
  200. return s, nil
  201. default:
  202. return s, fmt.Errorf("Unable to Cast %#v of type %v to []interface{}", i, reflect.TypeOf(i))
  203. }
  204. return s, fmt.Errorf("Unable to Cast %#v to []interface{}", i)
  205. }
  206. func ToStringSliceE(i interface{}) ([]string, error) {
  207. jww.DEBUG.Println("ToStringSliceE called on type:", reflect.TypeOf(i))
  208. var a []string
  209. switch v := i.(type) {
  210. case []interface{}:
  211. for _, u := range v {
  212. a = append(a, ToString(u))
  213. }
  214. return a, nil
  215. case []string:
  216. return v, nil
  217. default:
  218. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  219. }
  220. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  221. }
  222. func StringToDate(s string) (time.Time, error) {
  223. return parseDateWith(s, []string{
  224. time.RFC3339,
  225. "2006-01-02T15:04:05", // iso8601 without timezone
  226. time.RFC1123Z,
  227. time.RFC1123,
  228. time.RFC822Z,
  229. time.RFC822,
  230. time.ANSIC,
  231. time.UnixDate,
  232. time.RubyDate,
  233. "2006-01-02 15:04:05Z07:00",
  234. "02 Jan 06 15:04 MST",
  235. "2006-01-02",
  236. "02 Jan 2006",
  237. })
  238. }
  239. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  240. for _, dateType := range dates {
  241. if d, e = time.Parse(dateType, s); e == nil {
  242. return
  243. }
  244. }
  245. return d, errors.New(fmt.Sprintf("Unable to parse date: %s", s))
  246. }