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

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