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

254 lines
5.4 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 ToStringMapE(i interface{}) (map[string]interface{}, error) {
  148. jww.DEBUG.Println("ToStringMapE called on type:", reflect.TypeOf(i))
  149. var m = map[string]interface{}{}
  150. switch v := i.(type) {
  151. case map[interface{}]interface{}:
  152. for k, val := range v {
  153. m[ToString(k)] = val
  154. }
  155. return m, nil
  156. case map[string]interface{}:
  157. return v, nil
  158. default:
  159. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  160. }
  161. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  162. }
  163. func ToSliceE(i interface{}) ([]interface{}, error) {
  164. jww.DEBUG.Println("ToSliceE called on type:", reflect.TypeOf(i))
  165. var s []interface{}
  166. switch v := i.(type) {
  167. case []interface{}:
  168. fmt.Println("here")
  169. for _, u := range v {
  170. s = append(s, u)
  171. }
  172. return s, nil
  173. case []map[string]interface{}:
  174. for _, u := range v {
  175. s = append(s, u)
  176. }
  177. return s, nil
  178. default:
  179. return s, fmt.Errorf("Unable to Cast %#v of type %v to []interface{}", i, reflect.TypeOf(i))
  180. }
  181. return s, fmt.Errorf("Unable to Cast %#v to []interface{}", i)
  182. }
  183. func ToStringSliceE(i interface{}) ([]string, error) {
  184. jww.DEBUG.Println("ToStringSliceE called on type:", reflect.TypeOf(i))
  185. var a []string
  186. switch v := i.(type) {
  187. case []interface{}:
  188. for _, u := range v {
  189. a = append(a, ToString(u))
  190. }
  191. return a, nil
  192. case []string:
  193. return v, nil
  194. default:
  195. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  196. }
  197. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  198. }
  199. func StringToDate(s string) (time.Time, error) {
  200. return parseDateWith(s, []string{
  201. time.RFC3339,
  202. "2006-01-02T15:04:05", // iso8601 without timezone
  203. time.RFC1123Z,
  204. time.RFC1123,
  205. time.RFC822Z,
  206. time.RFC822,
  207. time.ANSIC,
  208. time.UnixDate,
  209. time.RubyDate,
  210. "2006-01-02 15:04:05Z07:00",
  211. "02 Jan 06 15:04 MST",
  212. "2006-01-02",
  213. "02 Jan 2006",
  214. })
  215. }
  216. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  217. for _, dateType := range dates {
  218. if d, e = time.Parse(dateType, s); e == nil {
  219. return
  220. }
  221. }
  222. return d, errors.New(fmt.Sprintf("Unable to parse date: %s", s))
  223. }