// Package reply 实现了Redis序列化协议(RESP)的回复处理功能。 // // 本包包含构建符合Redis RESP协议的各种响应格式的实现,支持以下类型: // - 简单字符串(Simple Strings): StatusReply // - 错误类型(Errors): StandardErrReply 及其子类型 // - 整型(Integers): IntReply // - 批量字符串(Bulk Strings): BulkReply // - 数组(Arrays): MultiBulkReply // // 所有回复类型都实现了 `resp.Reply` 接口,通过 `ToBytes()` 方法生成符合RESP协议格式的字节数据。 // // 示例用法: // // 创建整数回复 // // reply := NewIntReply(42) // output := reply.ToBytes() // 输出 ":42\r\n" // // 创建批量字符串回复 // // bulk := NewBulkReply([]byte("hello")) // output := bulk.ToBytes() // 输出 "$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 表示批量字符串回复的结构体。 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) } func NewBulkReply(arg []byte) *BulkReply { return &BulkReply{Arg: arg} } // MultiBulkReply 表示多条批量字符串回复的结构体。 数组 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() } func NewMultiBulkReply(args [][]byte) *MultiBulkReply { return &MultiBulkReply{Args: args} } // StatusReply 表示简单字符串回复的结构体。 // 例如:OK、PING、SET、GET等命令的回复。 // 对应Redis的"+"开头的回复。 // 例如:"+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) } func NewStatusReply(status string) *StatusReply { return &StatusReply{Status: status} } // IntReply 表示整数回复的结构体。 // 对应Redis的":"开头的回复。 // 例如:":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) } func NewIntReply(code int64) *IntReply { return &IntReply{Code: code} } // ErrorReply 表示错误回复的接口。 type ErrorReply interface { Error() string ToBytes() []byte } // StandardErrReply 表示标准错误回复的结构体。 // 对应Redis的"-"开头的回复。 // 例如:"-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) } func NewErrReply(status string) *StandardErrReply { return &StandardErrReply{Status: status} } // IsErrReply 判断回复是否为错误回复。 // 错误回复的第一个字节为"-"。 // 例如:"-ERR unknown command 'foobar'\r\n" func IsErrReply(reply resp.Reply) bool { return reply.ToBytes()[0] == '-' }