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  }