#[derive(Debug)]
pub enum DecodeError {
Invalid,
Incomplete
}
impl From<()> for DecodeError {
fn from(_: ()) -> Self {
DecodeError::Invalid
}
}
#[derive(Debug)]
pub enum EncodeError {
Overrun,
Encoding
}
pub trait EncodeBuffer {
fn push(&mut self, byte: u8) -> Result<(), EncodeError>;
fn push_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError>;
fn get_encoded_len(&self) -> usize;
fn get_raw<'a>(&'a self) -> &'a [u8];
}
pub trait DecodeBuffer {
fn read(&mut self) -> Result<u8, DecodeError>;
fn read_slice<'a>(&'a mut self, size: usize) -> Result<&'a [u8], DecodeError>;
fn get_read_len(&self) -> usize;
fn get_raw<'a>(&'a self) -> &'a [u8];
}
pub struct StaticBuffer<'a> {
ptr: usize,
buf: &'a mut [u8]
}
impl<'a> StaticBuffer<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
Self { ptr: 0, buf }
}
pub fn reset(&mut self) {
self.ptr = 0;
}
}
impl<'b> EncodeBuffer for StaticBuffer<'b> {
fn get_encoded_len(&self) -> usize {self.ptr}
fn get_raw<'a>(&'a self) -> &'a [u8] {&self.buf[0..self.ptr]}
fn push(&mut self, byte: u8) -> Result<(), EncodeError> {
if self.ptr >= self.buf.len() {return Err(EncodeError::Overrun);}
self.buf[self.ptr] = byte;
self.ptr+=1;
Ok(())
}
fn push_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError> {
if self.ptr + slice.len() > self.buf.len() {return Err(EncodeError::Overrun)}
self.buf[self.ptr..self.ptr+slice.len()].copy_from_slice(slice);
self.ptr += slice.len();
Ok(())
}
}
impl<'b> DecodeBuffer for StaticBuffer<'b> {
fn get_read_len(&self) -> usize {self.ptr}
fn get_raw<'a>(&'a self) -> &'a [u8] {&self.buf[0..self.ptr]}
fn read(&mut self) -> Result<u8, DecodeError> {
if self.buf.len() <= self.ptr {return Err(DecodeError::Incomplete);}
self.ptr+=1;
Ok(self.buf[self.ptr-1])
}
fn read_slice<'a>(&'a mut self, size: usize) -> Result<&'a [u8], DecodeError> {
if self.buf.len() < self.ptr+size {return Err(DecodeError::Incomplete);}
self.ptr+=size;
Ok(&self.buf[self.ptr-size..self.ptr])
}
}
pub trait Codec<Context>
where Self: Sized {
fn encode(self, buf: &mut impl EncodeBuffer, ctx: Context) -> Result<(), EncodeError>;
fn decode(buf: &mut impl DecodeBuffer, ctx: Context) -> Result<Self, DecodeError>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn static_buffer_read_singles() {
let mut slice: [u8;10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_read_len(), 0);
for i in 0..10 {
assert_eq!(buf.read().unwrap(), i);
}
buf.read().expect_err("Buf should be empty");
assert_eq!(buf.get_read_len(), 10);
}
#[test]
fn static_buffer_read_batches() {
let mut slice: [u8;10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_read_len(), 0);
for i in 0..5 {
assert_eq!(buf.read_slice(2).unwrap(), [i*2, i*2 + 1])
}
buf.read().expect_err("Buf should be empty");
assert_eq!(buf.get_read_len(), 10);
}
#[test]
fn static_buffer_write_singles() {
let mut slice: [u8;10] = [0; 10];
{
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..10 {
buf.push(i).unwrap();
}
buf.push(69).expect_err("Buf should be full");
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(slice, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
}
#[test]
fn static_buffer_write_batches() {
let mut slice: [u8;10] = [0; 10];
{
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..5 {
buf.push_slice(&[i*2, i*2 + 1]).unwrap();
}
buf.push(69).expect_err("Buf should be full");
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(slice, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
}
#[test]
fn static_buffer_reset() {
let mut slice: [u8;10] = [0; 10];
{
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..10 {
buf.push(i).unwrap();
}
assert_eq!(buf.get_encoded_len(), 10);
buf.reset();
assert_eq!(buf.get_encoded_len(), 0);
for i in 10..20 {
buf.push(i).unwrap();
}
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(slice, [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
}
}