Documentation
¶
Overview ¶
Package respcodec implements encoding and decoding for the Redis Serialization Protocol v2 (RESP2). It supports simple strings, errors, integers, bulk strings, arrays, null bulk strings, and null arrays.
Encoding: use Encode to serialize a value into a fresh buffer, or AppendEncode to write into a caller-supplied buffer for zero-allocation reuse.
Decoding: use Decode to parse a single complete frame and get back the decoded Go value, dispatched by wire-format prefix.
Example (DecodeHelpers) ¶
ss, _ := decodeSimpleString([]byte("+OK\r\n"))
fmt.Printf("%q\n", ss)
e, _ := decodeErrorString([]byte("-ERR unknown command\r\n"))
fmt.Printf("%q\n", e)
n, _ := decodeInteger([]byte(":42\r\n"))
fmt.Printf("%d\n", n)
s, _ := decodeBulkString([]byte("$5\r\nhello\r\n"))
fmt.Printf("%q\n", s)
err := decodeNullBulkString([]byte("$-1\r\n"))
fmt.Printf("%v\n", err == nil)
arr, _ := decodeArray([]byte("*3\r\n:1\r\n:2\r\n:3\r\n"))
fmt.Printf("%v\n", arr)
err = decodeNullArray([]byte("*-1\r\n"))
fmt.Printf("%v\n", err == nil)
Output: "OK" "ERR unknown command" 42 "hello" true [1 2 3] true
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var Null = nullBulkString{}
Null is the sentinel value for encoding a RESP null bulk string ($-1\r\n). It signals the absence of a value, distinct from an empty string.
var NullArr = nullArray{}
NullArr is the sentinel value for encoding a RESP null array (*-1\r\n). It is an alternative null representation used by commands like BLPOP on timeout. Prefer Null for general null values; use NullArr only when the protocol specifically requires it.
Functions ¶
func AppendEncode ¶
AppendEncode appends the RESP encoding of data into buf and returns the extended slice. It makes zero additional allocations when buf has sufficient capacity, making it suitable for callers that manage their own buffer — for example, writing directly to a net.Conn using a pooled buffer from sync.Pool.
On error, buf is returned in its original state (no partial bytes are left behind), so it is safe to reuse after a failed call.
Supported types are identical to Encode.
Example ¶
// Reuse a single buffer across multiple encodes — zero additional allocations
// when capacity is sufficient.
buf := make([]byte, 0, 128)
buf, _ = AppendEncode(buf, SimpleString("OK"))
buf, _ = AppendEncode(buf, errors.New("ERR unknown command"))
buf, _ = AppendEncode(buf, 42)
buf, _ = AppendEncode(buf, "hello")
fmt.Printf("%q\n", buf)
Output: "+OK\r\n-ERR unknown command\r\n:42\r\n$5\r\nhello\r\n"
func Decode ¶
Decode parses a single complete RESP frame from buf and returns the decoded Go value. The caller must supply exactly one complete frame with no trailing bytes.
Type mapping:
`+` → SimpleString `-` → error `:` → int `$` → string (nil for the null bulk string, "$-1\r\n") `*` → []any (nil for the null array, "*-1\r\n")
Example ¶
ss, _ := Decode([]byte("+OK\r\n"))
fmt.Println(ss)
e, _ := Decode([]byte("-ERR unknown command\r\n"))
fmt.Println(e)
n, _ := Decode([]byte(":42\r\n"))
fmt.Println(n)
s, _ := Decode([]byte("$5\r\nhello\r\n"))
fmt.Println(s)
null, _ := Decode([]byte("$-1\r\n"))
fmt.Println(null == nil)
arr, _ := Decode([]byte("*3\r\n:1\r\n:2\r\n:3\r\n"))
fmt.Println(arr)
nullArr, _ := Decode([]byte("*-1\r\n"))
fmt.Println(nullArr == nil)
_, err := Decode([]byte("?unknown\r\n"))
fmt.Println(err)
Output: OK ERR unknown command 42 hello true [1 2 3] true unknown RESP type sigil: '?'
func Encode ¶
Encode serializes a Go value into its RESP byte representation.
Supported types and their RESP encoding:
- SimpleString → +<value>\r\n (must not contain CR or LF)
- string → $<len>\r\n<data>\r\n (binary-safe bulk string)
- error → -<message>\r\n (must not contain CR or LF)
- int → :<value>\r\n
- []any → *<len>\r\n<elements> (each element encoded recursively)
- Null → $-1\r\n (null bulk string)
- NullArr → *-1\r\n (null array)
Returns (nil, error) for unsupported types, invalid input, or arrays containing an invalid element.
Encode allocates a single initial buffer and grows it as needed; for outputs that fit within 64 bytes this is typically one allocation. Array elements are written into the same buffer via the internal append-style encode function, avoiding per-element allocations. Use AppendEncode to supply your own buffer.
Example ¶
buf, _ := Encode(SimpleString("OK"))
fmt.Printf("%q\n", buf)
buf, _ = Encode(errors.New("ERR unknown command"))
fmt.Printf("%q\n", buf)
buf, _ = Encode(42)
fmt.Printf("%q\n", buf)
buf, _ = Encode("hello")
fmt.Printf("%q\n", buf)
buf, _ = Encode([]any{"GET", "key"})
fmt.Printf("%q\n", buf)
buf, _ = Encode(Null)
fmt.Printf("%q\n", buf)
buf, _ = Encode(NullArr)
fmt.Printf("%q\n", buf)
buf, err := Encode(3.14) // unknown type → nil, error
fmt.Printf("%v %v\n", buf, err)
Output: "+OK\r\n" "-ERR unknown command\r\n" ":42\r\n" "$5\r\nhello\r\n" "*2\r\n$3\r\nGET\r\n$3\r\nkey\r\n" "$-1\r\n" "*-1\r\n" [] unsupported type float64: cannot encode to RESP
Types ¶
type SimpleString ¶
type SimpleString string
SimpleString represents a RESP simple string (prefix '+'). Simple strings are for short status messages like "OK" or "PONG". They must not contain CR (\r) or LF (\n) characters. Use the plain string type for binary-safe bulk string encoding instead.
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
Package resp3 implements encoding and decoding for the RESP3 protocol (https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md), the superset of RESP2 used by Redis 6+ in protover 3 mode.
|
Package resp3 implements encoding and decoding for the RESP3 protocol (https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md), the superset of RESP2 used by Redis 6+ in protover 3 mode. |