-
Notifications
You must be signed in to change notification settings - Fork 85
Description
I’m working on a use case that involves interacting with RESP (Redis Serialization Protocol), and I’m using the redis-protocol crate—specifically the BytesFrame type.
I’m integrating this with compio’s codec API, whose Decoder trait is defined as:
fn decode(&mut self, buf: &[u8]) -> Result<Item, Error>;The redis_protocol::decode_bytes API expects a &Bytes, so in my current implementation I’m forced to convert the incoming &[u8] into an owned Bytes on every call:
impl Decoder<BytesFrame> for RespCodec {
type Error = RedisProtocolError;
fn decode(&mut self, buf: &[u8]) -> Result<BytesFrame, Self::Error> {
let buffer = Bytes::copy_from_slice(buf);
match decode_bytes(&buffer) {
Ok(Some((frame, _))) => Ok(frame),
Ok(None) => {
// not enough data to decode a full frame
todo!()
}
Err(e) => Err(e),
}
}
}This works functionally, but it requires copying the entire input buffer into a new Bytes allocation on every decode, which is potentially expensive—especially for a streaming protocol like RESP.
My questions are:
- Is this copying unavoidable given the
Decodertrait’s&[u8]input and ownedItemoutput? - Is there a more idiomatic or zero-copy way to integrate
redis-protocol’sdecode_byteswith compio’s framing/codec infrastructure? - Does compio provide a higher-level framing or buffer abstraction (e.g. based on
BytesMut) that would allow incremental decoding and buffer advancement, rather than re-decoding from a copied slice each time?
In other words, am I fundamentally constrained by the Decoder trait’s signature here, or is there a better approach I should be using for RESP-style streaming decoding?