github.com/hdt3213/godis@v1.2.9/redis/protocol/reply.go (about) 1 package protocol 2 3 import ( 4 "bytes" 5 "github.com/hdt3213/godis/interface/redis" 6 "strconv" 7 ) 8 9 var ( 10 11 // CRLF is the line separator of redis serialization protocol 12 CRLF = "\r\n" 13 ) 14 15 /* ---- Bulk Reply ---- */ 16 17 // BulkReply stores a binary-safe string 18 type BulkReply struct { 19 Arg []byte 20 } 21 22 // MakeBulkReply creates BulkReply 23 func MakeBulkReply(arg []byte) *BulkReply { 24 return &BulkReply{ 25 Arg: arg, 26 } 27 } 28 29 // ToBytes marshal redis.Reply 30 func (r *BulkReply) ToBytes() []byte { 31 if r.Arg == nil { 32 return nullBulkBytes 33 } 34 return []byte("$" + strconv.Itoa(len(r.Arg)) + CRLF + string(r.Arg) + CRLF) 35 } 36 37 /* ---- Multi Bulk Reply ---- */ 38 39 // MultiBulkReply stores a list of string 40 type MultiBulkReply struct { 41 Args [][]byte 42 } 43 44 // MakeMultiBulkReply creates MultiBulkReply 45 func MakeMultiBulkReply(args [][]byte) *MultiBulkReply { 46 return &MultiBulkReply{ 47 Args: args, 48 } 49 } 50 51 // ToBytes marshal redis.Reply 52 func (r *MultiBulkReply) ToBytes() []byte { 53 argLen := len(r.Args) 54 var buf bytes.Buffer 55 buf.WriteString("*" + strconv.Itoa(argLen) + CRLF) 56 for _, arg := range r.Args { 57 if arg == nil { 58 buf.WriteString("$-1" + CRLF) 59 } else { 60 buf.WriteString("$" + strconv.Itoa(len(arg)) + CRLF + string(arg) + CRLF) 61 } 62 } 63 return buf.Bytes() 64 } 65 66 /* ---- Multi Raw Reply ---- */ 67 68 // MultiRawReply store complex list structure, for example GeoPos command 69 type MultiRawReply struct { 70 Replies []redis.Reply 71 } 72 73 // MakeMultiRawReply creates MultiRawReply 74 func MakeMultiRawReply(replies []redis.Reply) *MultiRawReply { 75 return &MultiRawReply{ 76 Replies: replies, 77 } 78 } 79 80 // ToBytes marshal redis.Reply 81 func (r *MultiRawReply) ToBytes() []byte { 82 argLen := len(r.Replies) 83 var buf bytes.Buffer 84 buf.WriteString("*" + strconv.Itoa(argLen) + CRLF) 85 for _, arg := range r.Replies { 86 buf.Write(arg.ToBytes()) 87 } 88 return buf.Bytes() 89 } 90 91 /* ---- Status Reply ---- */ 92 93 // StatusReply stores a simple status string 94 type StatusReply struct { 95 Status string 96 } 97 98 // MakeStatusReply creates StatusReply 99 func MakeStatusReply(status string) *StatusReply { 100 return &StatusReply{ 101 Status: status, 102 } 103 } 104 105 // ToBytes marshal redis.Reply 106 func (r *StatusReply) ToBytes() []byte { 107 return []byte("+" + r.Status + CRLF) 108 } 109 110 // IsOKReply returns true if the given protocol is +OK 111 func IsOKReply(reply redis.Reply) bool { 112 return string(reply.ToBytes()) == "+OK\r\n" 113 } 114 115 /* ---- Int Reply ---- */ 116 117 // IntReply stores an int64 number 118 type IntReply struct { 119 Code int64 120 } 121 122 // MakeIntReply creates int protocol 123 func MakeIntReply(code int64) *IntReply { 124 return &IntReply{ 125 Code: code, 126 } 127 } 128 129 // ToBytes marshal redis.Reply 130 func (r *IntReply) ToBytes() []byte { 131 return []byte(":" + strconv.FormatInt(r.Code, 10) + CRLF) 132 } 133 134 /* ---- Error Reply ---- */ 135 136 // ErrorReply is an error and redis.Reply 137 type ErrorReply interface { 138 Error() string 139 ToBytes() []byte 140 } 141 142 // StandardErrReply represents server error 143 type StandardErrReply struct { 144 Status string 145 } 146 147 // MakeErrReply creates StandardErrReply 148 func MakeErrReply(status string) *StandardErrReply { 149 return &StandardErrReply{ 150 Status: status, 151 } 152 } 153 154 // IsErrorReply returns true if the given protocol is error 155 func IsErrorReply(reply redis.Reply) bool { 156 return reply.ToBytes()[0] == '-' 157 } 158 159 // ToBytes marshal redis.Reply 160 func (r *StandardErrReply) ToBytes() []byte { 161 return []byte("-" + r.Status + CRLF) 162 } 163 164 func (r *StandardErrReply) Error() string { 165 return r.Status 166 }