use crate::read::Read;
use crate::word_buffer::WordBuffer;
use crate::write::Write;
use crate::{Result, E};
#[derive(Default)]
pub struct Buffer(pub WordBuffer);
impl Buffer {
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Self(BufferTrait::with_capacity(capacity))
}
#[cfg(test)]
pub(crate) fn capacity(&self) -> usize {
self.0.capacity()
}
}
pub trait BufferTrait: Default {
type Writer: Write;
type Reader<'a>: Read;
type Context;
fn capacity(&self) -> usize;
fn with_capacity(capacity: usize) -> Self;
fn start_write(&mut self) -> Self::Writer;
fn finish_write(&mut self, writer: Self::Writer) -> &[u8];
fn start_read<'a, 'b>(&'a mut self, bytes: &'b [u8]) -> (Self::Reader<'a>, Self::Context)
where
'a: 'b;
fn finish_read(reader: Self::Reader<'_>, context: Self::Context) -> Result<()>;
fn finish_read_with_result<T>(
reader: Self::Reader<'_>,
context: Self::Context,
decode_result: Result<T>,
) -> Result<T> {
let finish_result = Self::finish_read(reader, context);
if let Err(e) = &finish_result {
if e.same(&E::Eof.e()) {
return Err(E::Eof.e());
}
}
let t = decode_result?;
finish_result?;
Ok(t)
}
}
#[cfg(all(test, not(miri), debug_assertions))]
mod tests {
use crate::bit_buffer::BitBuffer;
use crate::buffer::BufferTrait;
use crate::word_buffer::WordBuffer;
use paste::paste;
macro_rules! test_with_capacity {
($name:ty, $t:ty) => {
paste! {
#[test]
fn [<test_ $name _with_capacity>]() {
for cap in 0..200 {
let buf = $t::with_capacity(cap);
assert!(buf.capacity() >= cap, "with_capacity: {cap}, capacity {}", buf.capacity());
}
}
}
}
}
test_with_capacity!(bit_buffer, BitBuffer);
test_with_capacity!(word_buffer, WordBuffer);
}