Expand description
kevy-resp — a zero-dependency RESP (REdis Serialization Protocol) codec.
It covers what a client sends to drive commands — the RESP2 multi-bulk
request (*N\r\n$len\r\n…) and the inline form (a bare PING\r\n typed over
a raw connection) — plus the reply primitives a server writes back. Parsing
is incremental and allocation-light: parse_command returns Ok(None)
when more bytes are needed, so it composes with a streaming read loop.
Pure Rust, no dependencies. Part of the kevy key–value server.
§Example
use kevy_resp::{encode_bulk, encode_simple_string, parse_command};
// Parse one command from a request buffer.
let (cmd, consumed) = parse_command(b"*2\r\n$4\r\nECHO\r\n$2\r\nhi\r\n")
.unwrap() // not a protocol error
.unwrap(); // a complete frame was present
assert_eq!(cmd, vec![b"ECHO".to_vec(), b"hi".to_vec()]);
assert_eq!(consumed, 22);
// A partial frame asks for more bytes rather than erroring.
assert_eq!(parse_command(b"*1\r\n$4\r\nPI").unwrap(), None);
// Encode replies into a caller-owned buffer.
let mut out = Vec::new();
encode_simple_string(&mut out, "PONG");
encode_bulk(&mut out, b"hi");
assert_eq!(out, b"+PONG\r\n$2\r\nhi\r\n");Structs§
- Argv
- A parsed command’s argument vector.
- Argv
Borrowed - A parsed command’s argument vector that borrows its bytes from a contiguous input buffer.
- Argv
Iter - Iterator yielding each
ArgvView’s arguments as&[u8]slices. - Argv
Pool - A recycling pool of owned
Argvs. See the module docs for the cross-shard ownership cycle it serves.
Enums§
- Protocol
Error - Why a buffer could not (yet) be parsed into a command (or reply).
- Reply
- A parsed RESP reply (server → client) — the client-side counterpart of
the crate’s
encode_*functions (server-side encoders). - Resp
Version - Which version of RESP a connection is speaking. Negotiated via the
HELLOcommand — RESP2 is the default for backwards compatibility with every Redis 6.x and earlier client; RESP3 is opt-in viaHELLO 3and unlocks the additive reply types (Reply::Map/Reply::Set/Reply::Double/Reply::Boolean/Reply::Verbatim/Reply::BigNumber/Reply::Null/Reply::Push/Reply::BlobError) plus out-of-band push frames forPUBLISHdelivery.
Traits§
- Argv
View - Read-only view over a parsed command’s argument vector.
Functions§
- encode_
array_ len *<len>\r\n— an array header; follow withlenencoded elements.- encode_
big_ number (<digits>\r\n— arbitrary-precision integer carried as its string representation. We don’t ship a bignum type (charter: zero deps), so the caller hands in pre-formatted digit bytes.- encode_
blob_ error !<len>\r\n<error>\r\n— length-prefixed error. Use when the error payload contains CRLF (the simple-...shape can’t encode it).- encode_
boolean #t\r\n/#f\r\n— boolean.- encode_
bulk $<len>\r\n<data>\r\n- encode_
command - Encode a command as a RESP multi-bulk request (client → server):
*N\r\n$len\r\n<arg>\r\n…. The inverse ofparse_command. - encode_
double ,<value>\r\n— a double.inf/-inf/nanare valid wire payloads per spec; we forward Rust’s standard float formatting which emits exactly those tokens.- encode_
error -<s>\r\n- encode_
integer :<n>\r\n- encode_
map_ header %<count>\r\n— a map header. Follow withcount× 2 sub-replies (key₁ value₁ key₂ value₂ …). The count is the pair count, not the element count.- encode_
null _\r\n— RESP3 true null. RESP2 fallback is the existingcrate::encode_null_bulk($-1\r\n).- encode_
null_ bulk $-1\r\n— the RESP2 null bulk string.- encode_
push_ header ><count>\r\n— an out-of-band push frame header. Follow withcountsub-replies. The RESP3 client demultiplexes push frames from regular replies, so this is whatPUBLISH/ pattern-subscribe delivery uses when the consumer speaks RESP3.- encode_
set_ header ~<count>\r\n— a set header. Follow withcountsub-replies; the receiving client treats them as a set (dedup is its job; the wire doesn’t require it).- encode_
simple_ string +<s>\r\n- encode_
verbatim =<len>\r\n<fmt>:<data>\r\n— verbatim string.fmtMUST be a 3-byte format tag (b"txt",b"mkd",b"raw", …);datais the payload after the:separator. The wirelencovers the 3-byte fmt +:+ payload (solen = 4 + data.len()).- parse_
command - Attempt to parse one command from the front of
buf. - parse_
command_ borrowed - Parse one command from the front of
buf, recording each arg as a(start, end)range intobufrather than copying its bytes. - parse_
command_ into - Same as
parse_command, but writes into a caller-provided scratchArgvinstead of allocating a new one each call. The reactor stores oneArgvper shard and reuses it for every cmd on the local hot path; the internalVec<u8>+Vec<u32>capacities amortise to zero allocations per command after the first few cmds warm them. - parse_
reply - Parse one RESP reply from the front of
buf. Speaks RESP2 + RESP3.
Type Aliases§
- Command
- A parsed command:
argv, whereargv[0]is the command name.