| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // Package reply implements the Redis Serialization Protocol (RESP) reply handling functionality.
- //
- // This package contains implementations for building various response formats that comply with the Redis RESP protocol, supporting the following types:
- // - Simple Strings: StatusReply
- // - Errors: StandardErrReply and its subtypes
- // - Integers: IntReply
- // - Bulk Strings: BulkReply
- // - Arrays: MultiBulkReply
- //
- // All reply types implement the [resp.Reply](file:///Users/lixiaoming/go/src/github.com/runningwater/go-redis/interface/resp/reply.go#L7-L12) interface, generating byte data in the RESP protocol format through the [ToBytes()](file:///Users/lixiaoming/go/src/github.com/runningwater/go-redis/interface/resp/reply.go#L9-L9) method.
- //
- // Example usage:
- //
- // Create an integer reply
- //
- // reply := NewIntReply(42)
- // output := reply.ToBytes() // Output ":42\r\n"
- //
- // Create a bulk string reply
- //
- // bulk := NewBulkReply([]byte("hello"))
- // output := bulk.ToBytes() // Output "$5\r\nhello\r\n"
- package reply
- import (
- "bytes"
- "strconv"
- "github.com/runningwater/go-redis/interface/resp"
- )
- var (
- nullBulkReplyBytes = []byte("$-1")
- CRLF = "\r\n"
- )
- // BulkReply represents a bulk string reply structure.
- type BulkReply struct {
- Arg []byte // "test" => "$4\r\ntest\r\n"
- }
- func (b *BulkReply) String() string {
- return string(b.ToBytes())
- }
- func (b *BulkReply) ToBytes() []byte {
- if len(b.Arg) == 0 {
- return nullBulkReplyBytes
- }
- return []byte("$" + strconv.Itoa(len(b.Arg)) + CRLF + string(b.Arg) + CRLF)
- }
- // NewBulkReply creates a new bulk reply
- func NewBulkReply(arg []byte) *BulkReply {
- return &BulkReply{Arg: arg}
- }
- // MultiBulkReply represents a multi-bulk string reply structure.
- type MultiBulkReply struct {
- Args [][]byte
- }
- func (m *MultiBulkReply) String() string {
- return string(m.ToBytes())
- }
- func (m *MultiBulkReply) ToBytes() []byte {
- argLen := len(m.Args)
- var buf bytes.Buffer
- buf.WriteString("*" + strconv.Itoa(argLen) + CRLF)
- for _, arg := range m.Args {
- if arg == nil {
- buf.WriteString(string(nullBulkReplyBytes) + CRLF)
- } else {
- buf.WriteString("$" + strconv.Itoa(len(arg)) + CRLF + string(arg) + CRLF)
- }
- }
- return buf.Bytes()
- }
- // NewMultiBulkReply creates a new multi-bulk reply
- func NewMultiBulkReply(args [][]byte) *MultiBulkReply {
- return &MultiBulkReply{Args: args}
- }
- // StatusReply represents a simple string reply structure.
- // For example: OK, PING, SET, GET command replies.
- // Corresponds to Redis replies starting with "+".
- // For example: "+OK\r\n"
- type StatusReply struct {
- Status string
- }
- func (s *StatusReply) String() string {
- return string(s.ToBytes())
- }
- func (s *StatusReply) ToBytes() []byte {
- return []byte("+" + s.Status + CRLF)
- }
- // NewStatusReply creates a new status reply
- func NewStatusReply(status string) *StatusReply {
- return &StatusReply{Status: status}
- }
- // IntReply represents an integer reply structure.
- // Corresponds to Redis replies starting with ":".
- // For example: ":1\r\n"
- type IntReply struct {
- Code int64
- }
- func (i *IntReply) String() string {
- return string(i.ToBytes())
- }
- func (i *IntReply) ToBytes() []byte {
- return []byte(":" + strconv.FormatInt(i.Code, 10) + CRLF)
- }
- // NewIntReply creates a new integer reply
- func NewIntReply(code int64) *IntReply {
- return &IntReply{Code: code}
- }
- // ErrorReply represents an error reply interface.
- type ErrorReply interface {
- Error() string
- ToBytes() []byte
- }
- // StandardErrReply represents a standard error reply structure.
- // Corresponds to Redis replies starting with "-".
- // For example: "-ERR unknown command 'foobar'\r\n"
- type StandardErrReply struct {
- Status string
- }
- func (s *StandardErrReply) String() string {
- return string(s.ToBytes())
- }
- func (s *StandardErrReply) Error() string {
- return s.Status
- }
- func (s *StandardErrReply) ToBytes() []byte {
- return []byte("-" + s.Status + CRLF)
- }
- // NewErrReply creates a new error reply
- func NewErrReply(status string) *StandardErrReply {
- return &StandardErrReply{Status: status}
- }
- // IsErrReply checks if the reply is an error reply.
- // Error replies start with "-".
- // For example: "-ERR unknown command 'foobar'\r\n"
- func IsErrReply(reply resp.Reply) bool {
- toBytes := reply.ToBytes()
- return len(toBytes) > 0 && toBytes[0] == '-'
- }
|