use crate::{CommandReply, DecodeError};
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Decoder<const BUFLEN: usize = 512> {
buf: [u8; BUFLEN],
wpos: usize,
rpos: usize,
}
impl Default for Decoder<512> {
fn default() -> Self {
Self::new()
}
}
impl<const BUFLEN: usize> Decoder<BUFLEN> {
pub fn new() -> Self {
Self {
buf: [0; BUFLEN],
rpos: 0,
wpos: 0,
}
}
pub fn feed(&mut self, data: &[u8]) -> Result<usize, DecodeError> {
if data.len() > self.buf.len().saturating_sub(self.wpos) {
self.buf.copy_within(self.rpos..self.wpos, 0);
self.wpos = self.wpos.saturating_sub(self.rpos);
self.rpos = self.rpos.saturating_sub(self.rpos);
}
if self.wpos == self.buf.len() {
self.rpos = 0;
self.wpos = 0;
}
let copied = data.len().min(self.buf.len().saturating_sub(self.wpos));
self.buf[self.wpos..self.wpos + copied].copy_from_slice(&data[..copied]);
self.wpos += copied;
Ok(copied)
}
}
impl<const BUFLEN: usize> core::iter::Iterator for Decoder<BUFLEN> {
type Item = CommandReply;
fn next(&mut self) -> Option<Self::Item> {
while self.rpos < self.wpos {
match crate::decode(&self.buf[self.rpos..self.wpos]) {
Ok((consumed, reply)) => {
self.rpos += consumed;
return Some(reply);
}
Err(DecodeError::IncompleteData) => return None,
_ => (),
}
self.rpos += 1;
}
None
}
}