在Go中轻松安全地从一种数据类型转换为另一种数据类型
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

328 行
7.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. "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. i = indirect(i)
  17. jww.DEBUG.Println("ToTimeE called on type:", reflect.TypeOf(i))
  18. switch s := i.(type) {
  19. case time.Time:
  20. return s, nil
  21. case string:
  22. d, e := StringToDate(s)
  23. if e == nil {
  24. return d, nil
  25. }
  26. return time.Time{}, fmt.Errorf("Could not parse Date/Time format: %v\n", e)
  27. default:
  28. return time.Time{}, fmt.Errorf("Unable to Cast %#v to Time\n", i)
  29. }
  30. }
  31. func ToBoolE(i interface{}) (bool, error) {
  32. i = indirect(i)
  33. jww.DEBUG.Println("ToBoolE called on type:", reflect.TypeOf(i))
  34. switch b := i.(type) {
  35. case bool:
  36. return b, nil
  37. case nil:
  38. return false, nil
  39. case int:
  40. if i.(int) != 0 {
  41. return true, nil
  42. }
  43. return false, nil
  44. case string:
  45. return strconv.ParseBool(i.(string))
  46. default:
  47. return false, fmt.Errorf("Unable to Cast %#v to bool", i)
  48. }
  49. }
  50. func ToFloat64E(i interface{}) (float64, error) {
  51. i = indirect(i)
  52. jww.DEBUG.Println("ToFloat64E called on type:", reflect.TypeOf(i))
  53. switch s := i.(type) {
  54. case float64:
  55. return s, nil
  56. case float32:
  57. return float64(s), nil
  58. case int64:
  59. return float64(s), nil
  60. case int32:
  61. return float64(s), nil
  62. case int16:
  63. return float64(s), nil
  64. case int8:
  65. return float64(s), nil
  66. case int:
  67. return float64(s), nil
  68. case string:
  69. v, err := strconv.ParseFloat(s, 64)
  70. if err == nil {
  71. return float64(v), nil
  72. } else {
  73. return 0.0, fmt.Errorf("Unable to Cast %#v to float", i)
  74. }
  75. default:
  76. return 0.0, fmt.Errorf("Unable to Cast %#v to float", i)
  77. }
  78. }
  79. func ToIntE(i interface{}) (int, error) {
  80. i = indirect(i)
  81. jww.DEBUG.Println("ToIntE called on type:", reflect.TypeOf(i))
  82. switch s := i.(type) {
  83. case int:
  84. return s, nil
  85. case int64:
  86. return int(s), nil
  87. case int32:
  88. return int(s), nil
  89. case int16:
  90. return int(s), nil
  91. case int8:
  92. return int(s), nil
  93. case string:
  94. v, err := strconv.ParseInt(s, 0, 0)
  95. if err == nil {
  96. return int(v), nil
  97. } else {
  98. return 0, fmt.Errorf("Unable to Cast %#v to int", i)
  99. }
  100. case float64:
  101. return int(s), nil
  102. case bool:
  103. if bool(s) {
  104. return 1, nil
  105. } else {
  106. return 0, nil
  107. }
  108. case nil:
  109. return 0, nil
  110. default:
  111. return 0, fmt.Errorf("Unable to Cast %#v to int", i)
  112. }
  113. }
  114. // From html/template/content.go
  115. // Copyright 2011 The Go Authors. All rights reserved.
  116. // indirect returns the value, after dereferencing as many times
  117. // as necessary to reach the base type (or nil).
  118. func indirect(a interface{}) interface{} {
  119. if a == nil {
  120. return nil
  121. }
  122. if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
  123. // Avoid creating a reflect.Value if it's not a pointer.
  124. return a
  125. }
  126. v := reflect.ValueOf(a)
  127. for v.Kind() == reflect.Ptr && !v.IsNil() {
  128. v = v.Elem()
  129. }
  130. return v.Interface()
  131. }
  132. // From html/template/content.go
  133. // Copyright 2011 The Go Authors. All rights reserved.
  134. // indirectToStringerOrError returns the value, after dereferencing as many times
  135. // as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
  136. // or error,
  137. func indirectToStringerOrError(a interface{}) interface{} {
  138. if a == nil {
  139. return nil
  140. }
  141. var errorType = reflect.TypeOf((*error)(nil)).Elem()
  142. var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
  143. v := reflect.ValueOf(a)
  144. for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
  145. v = v.Elem()
  146. }
  147. return v.Interface()
  148. }
  149. func ToStringE(i interface{}) (string, error) {
  150. i = indirectToStringerOrError(i)
  151. jww.DEBUG.Println("ToStringE called on type:", reflect.TypeOf(i))
  152. switch s := i.(type) {
  153. case string:
  154. return s, nil
  155. case float64:
  156. return strconv.FormatFloat(i.(float64), 'f', -1, 64), nil
  157. case int:
  158. return strconv.FormatInt(int64(i.(int)), 10), nil
  159. case []byte:
  160. return string(s), nil
  161. case template.HTML:
  162. return string(s), nil
  163. case nil:
  164. return "", nil
  165. case fmt.Stringer:
  166. return s.String(), nil
  167. case error:
  168. return s.Error(), nil
  169. default:
  170. return "", fmt.Errorf("Unable to Cast %#v to string", i)
  171. }
  172. }
  173. func ToStringMapStringE(i interface{}) (map[string]string, error) {
  174. jww.DEBUG.Println("ToStringMapStringE called on type:", reflect.TypeOf(i))
  175. var m = map[string]string{}
  176. switch v := i.(type) {
  177. case map[interface{}]interface{}:
  178. for k, val := range v {
  179. m[ToString(k)] = ToString(val)
  180. }
  181. return m, nil
  182. case map[string]interface{}:
  183. for k, val := range v {
  184. m[ToString(k)] = ToString(val)
  185. }
  186. return m, nil
  187. case map[string]string:
  188. return v, nil
  189. default:
  190. return m, fmt.Errorf("Unable to Cast %#v to map[string]string", i)
  191. }
  192. return m, fmt.Errorf("Unable to Cast %#v to map[string]string", i)
  193. }
  194. func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
  195. jww.DEBUG.Println("ToStringMapBoolE called on type:", reflect.TypeOf(i))
  196. var m = map[string]bool{}
  197. switch v := i.(type) {
  198. case map[interface{}]interface{}:
  199. for k, val := range v {
  200. m[ToString(k)] = ToBool(val)
  201. }
  202. return m, nil
  203. case map[string]interface{}:
  204. for k, val := range v {
  205. m[ToString(k)] = ToBool(val)
  206. }
  207. return m, nil
  208. case map[string]bool:
  209. return v, nil
  210. default:
  211. return m, fmt.Errorf("Unable to Cast %#v to map[string]bool", i)
  212. }
  213. return m, fmt.Errorf("Unable to Cast %#v to map[string]bool", i)
  214. }
  215. func ToStringMapE(i interface{}) (map[string]interface{}, error) {
  216. jww.DEBUG.Println("ToStringMapE called on type:", reflect.TypeOf(i))
  217. var m = map[string]interface{}{}
  218. switch v := i.(type) {
  219. case map[interface{}]interface{}:
  220. for k, val := range v {
  221. m[ToString(k)] = val
  222. }
  223. return m, nil
  224. case map[string]interface{}:
  225. return v, nil
  226. default:
  227. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  228. }
  229. return m, fmt.Errorf("Unable to Cast %#v to map[string]interface{}", i)
  230. }
  231. func ToSliceE(i interface{}) ([]interface{}, error) {
  232. jww.DEBUG.Println("ToSliceE called on type:", reflect.TypeOf(i))
  233. var s []interface{}
  234. switch v := i.(type) {
  235. case []interface{}:
  236. for _, u := range v {
  237. s = append(s, u)
  238. }
  239. return s, nil
  240. case []map[string]interface{}:
  241. for _, u := range v {
  242. s = append(s, u)
  243. }
  244. return s, nil
  245. default:
  246. return s, fmt.Errorf("Unable to Cast %#v of type %v to []interface{}", i, reflect.TypeOf(i))
  247. }
  248. return s, fmt.Errorf("Unable to Cast %#v to []interface{}", i)
  249. }
  250. func ToStringSliceE(i interface{}) ([]string, error) {
  251. jww.DEBUG.Println("ToStringSliceE called on type:", reflect.TypeOf(i))
  252. var a []string
  253. switch v := i.(type) {
  254. case []interface{}:
  255. for _, u := range v {
  256. a = append(a, ToString(u))
  257. }
  258. return a, nil
  259. case []string:
  260. return v, nil
  261. default:
  262. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  263. }
  264. return a, fmt.Errorf("Unable to Cast %#v to []string", i)
  265. }
  266. func StringToDate(s string) (time.Time, error) {
  267. return parseDateWith(s, []string{
  268. time.RFC3339,
  269. "2006-01-02T15:04:05", // iso8601 without timezone
  270. time.RFC1123Z,
  271. time.RFC1123,
  272. time.RFC822Z,
  273. time.RFC822,
  274. time.ANSIC,
  275. time.UnixDate,
  276. time.RubyDate,
  277. "2006-01-02 15:04:05Z07:00",
  278. "02 Jan 06 15:04 MST",
  279. "2006-01-02",
  280. "02 Jan 2006",
  281. })
  282. }
  283. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  284. for _, dateType := range dates {
  285. if d, e = time.Parse(dateType, s); e == nil {
  286. return
  287. }
  288. }
  289. return d, errors.New(fmt.Sprintf("Unable to parse date: %s", s))
  290. }