codec 0.0.6

Codec trait to assist in making codecs
Documentation
use heapless::Deque;

use crate::{DecodeError, EncodeError};



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;
}

pub trait DecodeBuffer {
    fn read(&mut self) -> Result<u8, DecodeError>;
    fn read_slice(&mut self, buf: &mut [u8]) -> Result<(),DecodeError>;
    fn get_read_len(&self) -> usize;
}

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;
    }
    /// Gets the slice of data processed thus far
    pub fn get_raw(&'a self) -> &'a [u8] {
        &self.buf[0..self.ptr]
    }
}

impl<'b> EncodeBuffer for StaticBuffer<'b> {
    fn get_encoded_len(&self) -> usize {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 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(&mut self, slice: &mut [u8]) -> Result<(), DecodeError> {
        // TODO: Verify length checks (usize???)
        if slice.len() > (self.buf.len() - self.ptr)  {return Err(DecodeError::Incomplete);}

        self.ptr+=slice.len();
        slice.copy_from_slice(&self.buf[self.ptr-slice.len()..self.ptr]);

        Ok(())
    }
}

pub struct RollingBuffer<'a, const SIZE: usize> {
    buf: &'a mut Deque<u8, SIZE>
}

impl<'a, const SIZE: usize> RollingBuffer<'a, SIZE> {
    pub fn new(buf: &'a mut Deque<u8, SIZE>) -> Self {
        RollingBuffer { buf }
    }
    pub fn reset(&mut self) {
        self.buf.clear();
    }
    pub fn get_raw(&'a self) -> &'a Deque<u8, SIZE> {
        &self.buf
    }
    /// Pops the first element off the queue
    pub fn pop(&mut self) -> Option<u8> {
        self.buf.pop_front()
    }
}

impl<'a, const SIZE: usize> EncodeBuffer for RollingBuffer<'a, SIZE> {
    fn get_encoded_len(&self) -> usize {self.buf.len()}
    fn push(&mut self, byte: u8) -> Result<(), EncodeError> {
        if self.buf.push_back(byte).is_err() {
            Err(EncodeError::Overrun)
        } else {
            Ok(())
        }
    }
    fn push_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError> {
        for item in slice {
            if self.buf.push_back(*item).is_err() {
                return Err(EncodeError::Overrun);
            }
        }
        Ok(())
    }
}

impl<'a, const SIZE: usize> DecodeBuffer for RollingBuffer<'a, SIZE> {
    fn get_read_len(&self) -> usize {self.buf.capacity()-self.buf.len()}
    fn read(&mut self) -> Result<u8, DecodeError> {
        if let Some(item) = self.buf.pop_front() {
            Ok(item)
        } else {
            Err(DecodeError::Incomplete)
        }
    }
    fn read_slice(&mut self, buf: &mut [u8]) -> Result<(), DecodeError> {
        if self.buf.len() < buf.len() {return Err(DecodeError::Incomplete);}

        for i in 0..buf.len() {
            buf[i] = self
                .buf
                .pop_front()
                .expect("Since we already early returned for bad len, we should always have enough bytes to read");
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use heapless::Vec;

    // TODO: Test pulling too much from buffer doesn't corrupt buffer.
    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 {
            let mut slice = [0;2];
            buf.read_slice(&mut slice).unwrap();
            assert_eq!(slice, [i*2, i*2 + 1]);
        }
        buf.read().expect_err("Buf should be empty");
        assert_eq!(buf.get_read_len(), 10);
    }

    #[test]
    fn static_buffer_read_larger_than_buffer() {
        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);
        
        let mut too_large = [0;11];
        buf
            .read_slice(&mut too_large)
            .expect_err("Should not be able to read more than the buffers size");
        assert_eq!(buf.get_read_len(), 0);
    }

    #[test]
    fn static_buffer_original_buffer_restored_on_failed_read() {
        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);
        
        let mut first = [0;5];
        buf
            .read_slice(&mut first)
            .expect("Should be able to read data within range");
        assert_eq!(buf.get_read_len(), 5);
        let mut second = [0;6];
        buf
            .read_slice(&mut second)
            .expect_err("Should not be able to read more than the buffers size");
        assert_eq!(buf.get_read_len(), 5);
    }

    #[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]);
    }

    #[test]
    fn rolling_buffer_read_singles() {
        let mut inner = Deque::<u8, 10>::new();
        for i in 0..10 {
            inner.push_back(i as u8).expect("Pushing within size should succeed");
        }
        let mut buf = RollingBuffer::new(&mut inner);
        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 rolling_buffer_read_batches() {
        let mut inner = Deque::<u8, 10>::new();
        for i in 0..10 {
            inner.push_back(i as u8).expect("Pushing within size should succeed");
        }
        let mut buf = RollingBuffer::new(&mut inner);
        assert_eq!(buf.get_read_len(), 0);
        for i in 0..5 {
            let mut slice = [0;2];
            buf.read_slice(&mut slice).unwrap();
            assert_eq!(slice, [i*2, i*2 + 1]);
        }
        buf.read().expect_err("Buf should be empty");
        assert_eq!(buf.get_read_len(), 10);
    }

    #[test]
    fn rolling_buffer_read_larger_than_buffer() {
        let mut inner = Deque::<u8, 10>::new();
        for i in 0..10 {
            inner.push_back(i as u8).expect("Pushing within size should succeed");
        }
        let mut buf = RollingBuffer::new(&mut inner);
        assert_eq!(buf.get_read_len(), 0);
        
        let mut too_large = [0;11];
        buf
            .read_slice(&mut too_large)
            .expect_err("Should not be able to read more than the buffers size");
        assert_eq!(buf.get_read_len(), 0);
    }

    #[test]
    fn rolling_buffer_original_buffer_restored_on_failed_read() {
        let mut inner = Deque::<u8, 10>::new();
        for i in 0..10 {
            inner.push_back(i as u8).expect("Pushing within size should succeed");
        }
        let mut buf = RollingBuffer::new(&mut inner);
        assert_eq!(buf.get_read_len(), 0);
        
        let mut first = [0;5];
        buf
            .read_slice(&mut first)
            .expect("Should be able to read data within range");
        assert_eq!(buf.get_read_len(), 5);
        let mut second = [0;6];
        buf
            .read_slice(&mut second)
            .expect_err("Should not be able to read more than the buffers size");
        assert_eq!(buf.get_read_len(), 5);
    }

    #[test]
    fn rolling_buffer_write_singles() {
        let mut inner = Deque::<u8, 10>::new();
        {
            let mut buf = RollingBuffer::new(&mut inner);
            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!(inner.iter().map(|x| *x).collect::<Vec<u8, 10>>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    }

    #[test]
    fn rolling_buffer_write_batches() {
        let mut inner = Deque::<u8, 10>::new();
        {
            let mut buf = RollingBuffer::new(&mut inner);
            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!(inner.iter().map(|x| *x).collect::<Vec<u8, 10>>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    }

    #[test]
    fn rolling_buffer_reset() {
        let mut inner = Deque::<u8, 10>::new();
        {
            let mut buf = RollingBuffer::new(&mut inner);
            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!(inner.iter().map(|x| *x).collect::<Vec<u8, 10>>(), [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
    }
}