reply.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // Copyright 2012 Gary Burd
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. // License for the specific language governing permissions and limitations
  13. // under the License.
  14. package redis
  15. import (
  16. "errors"
  17. "fmt"
  18. "strconv"
  19. )
  20. var ErrNil = errors.New("redigo: nil returned")
  21. // xValues is deprecated. Use Scan instead.
  22. func xValues(multiBulk []interface{}, values ...interface{}) ([]interface{}, error) {
  23. if len(multiBulk) < len(values) {
  24. return nil, errors.New("redigo Values: short multibulk")
  25. }
  26. var err error
  27. for i, value := range values {
  28. bulk := multiBulk[i]
  29. if bulk != nil {
  30. switch value := value.(type) {
  31. case *string:
  32. *value, err = String(bulk, nil)
  33. case *int:
  34. *value, err = Int(bulk, nil)
  35. case *bool:
  36. *value, err = Bool(bulk, nil)
  37. case *[]byte:
  38. *value, err = Bytes(bulk, nil)
  39. default:
  40. panic("Value type not supported")
  41. }
  42. if err != nil {
  43. break
  44. }
  45. }
  46. }
  47. return multiBulk[len(values):], err
  48. }
  49. // Int is a helper that converts a command reply to an integer. If err is not
  50. // equal to nil, then Int returns 0, err. Otherwise, Int converts the
  51. // reply to an int as follows:
  52. //
  53. // Reply type Result
  54. // integer int(reply), nil
  55. // bulk strconv.ParseInt(reply, 10, 0)
  56. // nil 0, ErrNil
  57. // other 0, error
  58. func Int(reply interface{}, err error) (int, error) {
  59. if err != nil {
  60. return 0, err
  61. }
  62. switch reply := reply.(type) {
  63. case int64:
  64. x := int(reply)
  65. if int64(x) != reply {
  66. return 0, strconv.ErrRange
  67. }
  68. return x, nil
  69. case []byte:
  70. n, err := strconv.ParseInt(string(reply), 10, 0)
  71. return int(n), err
  72. case nil:
  73. return 0, ErrNil
  74. case Error:
  75. return 0, reply
  76. }
  77. return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply)
  78. }
  79. // String is a helper that converts a command reply to a string. If err is not
  80. // equal to nil, then String returns "", err. Otherwise String converts the
  81. // reply to a string as follows:
  82. //
  83. // Reply type Result
  84. // bulk string(reply), nil
  85. // string reply, nil
  86. // nil "", ErrNil
  87. // other "", error
  88. func String(reply interface{}, err error) (string, error) {
  89. if err != nil {
  90. return "", err
  91. }
  92. switch reply := reply.(type) {
  93. case []byte:
  94. return string(reply), nil
  95. case string:
  96. return reply, nil
  97. case nil:
  98. return "", ErrNil
  99. case Error:
  100. return "", reply
  101. }
  102. return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply)
  103. }
  104. // Bytes is a helper that converts a command reply to a slice of bytes. If err
  105. // is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts
  106. // the reply to a slice of bytes as follows:
  107. //
  108. // Reply type Result
  109. // bulk reply, nil
  110. // string []byte(reply), nil
  111. // nil nil, ErrNil
  112. // other nil, error
  113. func Bytes(reply interface{}, err error) ([]byte, error) {
  114. if err != nil {
  115. return nil, err
  116. }
  117. switch reply := reply.(type) {
  118. case []byte:
  119. return reply, nil
  120. case string:
  121. return []byte(reply), nil
  122. case nil:
  123. return nil, ErrNil
  124. case Error:
  125. return nil, reply
  126. }
  127. return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply)
  128. }
  129. // Bool is a helper that converts a command reply to a boolean. If err is not
  130. // equal to nil, then Bool returns false, err. Otherwise Bool converts the
  131. // reply to boolean as follows:
  132. //
  133. // Reply type Result
  134. // integer value != 0, nil
  135. // bulk strconv.ParseBool(reply)
  136. // nil false, ErrNil
  137. // other false, error
  138. func Bool(reply interface{}, err error) (bool, error) {
  139. if err != nil {
  140. return false, err
  141. }
  142. switch reply := reply.(type) {
  143. case int64:
  144. return reply != 0, nil
  145. case []byte:
  146. return strconv.ParseBool(string(reply))
  147. case nil:
  148. return false, ErrNil
  149. case Error:
  150. return false, reply
  151. }
  152. return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply)
  153. }
  154. // MultiBulk is deprecated. Use Values.
  155. func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) }
  156. // Values is a helper that converts a multi-bulk command reply to a
  157. // []interface{}. If err is not equal to nil, then Values returns nil, err.
  158. // Otherwise, Multi converts the reply as follows:
  159. //
  160. // Reply type Result
  161. // multi-bulk reply, nil
  162. // nil nil, ErrNil
  163. // other nil, error
  164. func Values(reply interface{}, err error) ([]interface{}, error) {
  165. if err != nil {
  166. return nil, err
  167. }
  168. switch reply := reply.(type) {
  169. case []interface{}:
  170. return reply, nil
  171. case nil:
  172. return nil, ErrNil
  173. case Error:
  174. return nil, reply
  175. }
  176. return nil, fmt.Errorf("redigo: unexpected type for Multi, got type %T", reply)
  177. }