///|
/// Streaming PackStream reader/writer used by the Bolt transport layer.
///
/// The [`packstream`] entry points work on whole `Bytes` buffers. These types
/// add an incremental interface on top of the same codec: a [`Writer`]
/// accumulates values onto a growable buffer, and a [`Reader`] reads values
/// one at a time from a cursor. The Bolt layer needs both — it assembles a
/// message with a writer, then reassembles and walks a response with a reader.
///|
/// A growable PackStream writer. Values are encoded onto an internal buffer and
/// flushed with [`Writer::to_bytes`] once a whole message has been assembled.
pub struct Writer {
buf : Buffer
}
///|
pub fn Writer::new() -> Writer {
{ buf: Buffer::Buffer(), }
}
///|
/// Append `value` to the writer's buffer.
pub fn Writer::write(self : Writer, value : PackStreamValue) -> Unit {
write_value(self.buf, value)
}
///|
/// Flush the accumulated bytes.
pub fn Writer::to_bytes(self : Writer) -> Bytes {
self.buf.to_bytes()
}
///|
/// A PackStream reader over a byte buffer with a cursor.
pub struct Reader {
bytes : Bytes
mut pos : Int
}
///|
pub fn Reader::new(bytes : Bytes) -> Reader {
{ bytes, pos: 0, }
}
///|
/// Read the next value at the cursor, advancing past it. Returns `None` on
/// malformed or truncated input (the cursor is left unchanged in that case).
pub fn Reader::read(self : Reader) -> PackStreamValue? {
match read_value(self.bytes, self.pos) {
None => None
Some((value, next)) => {
self.pos = next
Some(value)
}
}
}
///|
/// Whether the reader has consumed all of its input.
pub fn Reader::eof(self : Reader) -> Bool {
self.pos >= self.bytes.length()
}
///|
/// Number of bytes left to consume.
pub fn Reader::remaining(self : Reader) -> Int {
self.bytes.length() - self.pos
}