introduce ReaderMut

Co-authored-by: Jorge Aparicio <jorge.aparicio@ferrous-systems.com>
This commit is contained in:
Christian Poveda 2023-12-07 12:21:46 -05:00 committed by Daniel McCarney
parent b068ca3643
commit ef41a6dbd6
1 changed files with 63 additions and 1 deletions

View File

@ -1,7 +1,7 @@
use crate::error::InvalidMessage;
use alloc::vec::Vec;
use core::fmt::Debug;
use core::{fmt::Debug, mem};
/// Wrapper over a slice of bytes that allows reading chunks from
/// with the current position state held using a cursor.
@ -85,6 +85,68 @@ impl<'a> Reader<'a> {
}
}
/// A version of [`Reader`] that operates on mutable slices
pub(crate) struct ReaderMut<'a> {
/// The underlying buffer storing the readers content
buffer: &'a mut [u8],
used: usize,
}
#[allow(dead_code)] // TODO(@cpu): remove in "introduce and expose BorrowedOpaqueMessage"
impl<'a> ReaderMut<'a> {
pub(crate) fn init(bytes: &'a mut [u8]) -> Self {
Self {
buffer: bytes,
used: 0,
}
}
pub(crate) fn sub(&mut self, length: usize) -> Result<Self, InvalidMessage> {
match self.take(length) {
Some(bytes) => Ok(ReaderMut::init(bytes)),
None => Err(InvalidMessage::MessageTooShort),
}
}
pub(crate) fn rest(&mut self) -> &'a mut [u8] {
let rest = mem::take(&mut self.buffer);
self.used += rest.len();
rest
}
pub(crate) fn take(&mut self, length: usize) -> Option<&'a mut [u8]> {
if self.left() < length {
return None;
}
let (taken, rest) = mem::take(&mut self.buffer).split_at_mut(length);
self.used += taken.len();
self.buffer = rest;
Some(taken)
}
pub(crate) fn used(&self) -> usize {
self.used
}
pub(crate) fn left(&self) -> usize {
self.buffer.len()
}
pub(crate) fn as_reader<T>(&mut self, f: impl FnOnce(&mut Reader) -> T) -> T {
let mut r = Reader {
buffer: self.buffer,
cursor: 0,
};
let ret = f(&mut r);
let cursor = r.cursor;
self.used += cursor;
let (_used, rest) = mem::take(&mut self.buffer).split_at_mut(cursor);
self.buffer = rest;
ret
}
}
/// Trait for implementing encoding and decoding functionality
/// on something.
pub trait Codec: Debug + Sized {