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

200 lines
3.6 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. "strconv"
  10. "time"
  11. jww "github.com/spf13/jwalterweatherman"
  12. )
  13. func ToTimeE(i interface{}) (tim time.Time, ok bool) {
  14. switch s := i.(type) {
  15. case time.Time:
  16. return s, true
  17. case string:
  18. d, e := StringToDate(s)
  19. if e == nil {
  20. return d, true
  21. }
  22. jww.ERROR.Println("Could not parse Date/Time format:", e)
  23. return time.Time{}, false
  24. default:
  25. jww.ERROR.Printf("Unable to Cast %#v to Time", i)
  26. return time.Time{}, false
  27. }
  28. return time.Time{}, false
  29. }
  30. func ToBoolE(i interface{}) (bool, bool) {
  31. switch b := i.(type) {
  32. case bool:
  33. return b, true
  34. case nil:
  35. return false, true
  36. case int:
  37. if i.(int) > 0 {
  38. return true, true
  39. }
  40. return false, true
  41. default:
  42. return false, false
  43. jww.ERROR.Printf("Unable to Cast %#v to bool", i)
  44. }
  45. return false, false
  46. }
  47. func ToStringMapStringE(i interface{}) (map[string]string, bool) {
  48. var m = map[string]string{}
  49. switch v := i.(type) {
  50. case map[interface{}]interface{}:
  51. for k, val := range v {
  52. m[ToString(k)] = ToString(val)
  53. }
  54. default:
  55. return m, false
  56. }
  57. return m, true
  58. }
  59. func ToStringMapE(i interface{}) (map[string]interface{}, bool) {
  60. var m = map[string]interface{}{}
  61. switch v := i.(type) {
  62. case map[interface{}]interface{}:
  63. for k, val := range v {
  64. m[ToString(k)] = val
  65. }
  66. default:
  67. return m, false
  68. }
  69. return m, true
  70. }
  71. func ToStringSliceE(i interface{}) ([]string, bool) {
  72. var a []string
  73. switch v := i.(type) {
  74. case []interface{}:
  75. for _, u := range v {
  76. a = append(a, ToString(u))
  77. }
  78. default:
  79. return a, false
  80. }
  81. return a, true
  82. }
  83. func ToFloat64E(i interface{}) (float64, bool) {
  84. switch s := i.(type) {
  85. case float64:
  86. return s, true
  87. case float32:
  88. return float64(s), true
  89. case string:
  90. v, err := strconv.ParseFloat(s, 64)
  91. if err == nil {
  92. return float64(v), true
  93. } else {
  94. jww.ERROR.Printf("Unable to Cast %#v to float", i)
  95. jww.ERROR.Println(err)
  96. }
  97. default:
  98. jww.ERROR.Printf("Unable to Cast %#v to float", i)
  99. }
  100. return 0.0, false
  101. }
  102. func ToIntE(i interface{}) (int, bool) {
  103. switch s := i.(type) {
  104. case int:
  105. return s, true
  106. case int64:
  107. return int(s), true
  108. case int32:
  109. return int(s), true
  110. case int16:
  111. return int(s), true
  112. case int8:
  113. return int(s), true
  114. case string:
  115. v, err := strconv.ParseInt(s, 0, 0)
  116. if err == nil {
  117. return int(v), true
  118. } else {
  119. jww.ERROR.Printf("Unable to Cast %#v to int", i)
  120. jww.ERROR.Println(err)
  121. }
  122. case bool:
  123. if bool(s) {
  124. return 1, true
  125. } else {
  126. return 0, true
  127. }
  128. default:
  129. jww.ERROR.Printf("Unable to Cast %#v to int", i)
  130. }
  131. return 0, false
  132. }
  133. func ToStringE(i interface{}) (string, bool) {
  134. switch s := i.(type) {
  135. case string:
  136. return s, true
  137. case float64:
  138. return strconv.FormatFloat(i.(float64), 'f', -1, 64), true
  139. case int:
  140. return strconv.FormatInt(int64(i.(int)), 10), true
  141. case nil:
  142. return "", true
  143. default:
  144. jww.ERROR.Printf("Unable to Cast %#v to string", i)
  145. }
  146. return "", false
  147. }
  148. func StringToDate(s string) (time.Time, error) {
  149. return parseDateWith(s, []string{
  150. time.RFC3339,
  151. "2006-01-02T15:04:05", // iso8601 without timezone
  152. time.RFC1123Z,
  153. time.RFC1123,
  154. time.RFC822Z,
  155. time.RFC822,
  156. time.ANSIC,
  157. time.UnixDate,
  158. time.RubyDate,
  159. "2006-01-02 15:04:05Z07:00",
  160. "02 Jan 06 15:04 MST",
  161. "2006-01-02",
  162. "02 Jan 2006",
  163. })
  164. }
  165. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  166. for _, dateType := range dates {
  167. if d, e = time.Parse(dateType, s); e == nil {
  168. return
  169. }
  170. }
  171. return d, errors.New(fmt.Sprintf("Unable to parse date: %s", s))
  172. }