use super::RmpRead;
use crate::decode::RmpReadErr;
use core::fmt::{Display, Formatter};
#[derive(Debug)]
#[non_exhaustive]
pub enum BytesReadError {
InsufficientBytes {
expected: usize,
actual: usize,
position: u64,
},
}
impl Display for BytesReadError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match *self {
Self::InsufficientBytes { expected, actual, position } => {
write!(f, "Expected at least bytes {expected}, but only got {actual} (pos {position})")
},
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for BytesReadError {}
impl RmpReadErr for BytesReadError {}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Bytes<'a> {
current_position: u64,
bytes: &'a [u8],
}
impl<'a> Bytes<'a> {
#[inline]
#[must_use]
pub const fn new(bytes: &'a [u8]) -> Self {
Bytes { bytes, current_position: 0 }
}
#[inline]
#[must_use]
pub const fn remaining_slice(&self) -> &'a [u8] {
self.bytes
}
#[inline]
#[must_use]
pub const fn position(&self) -> u64 {
self.current_position
}
}
impl<'a> From<&'a [u8]> for Bytes<'a> {
#[inline]
fn from(bytes: &'a [u8]) -> Self {
Bytes { bytes, current_position: 0 }
}
}
impl RmpRead for Bytes<'_> {
type Error = BytesReadError;
#[inline]
fn read_u8(&mut self) -> Result<u8, Self::Error> {
if let Some((&first, newly_remaining)) = self.bytes.split_first() {
self.bytes = newly_remaining;
self.current_position += 1;
Ok(first)
} else {
Err(BytesReadError::InsufficientBytes {
expected: 1,
actual: 0,
position: self.current_position,
})
}
}
#[inline]
fn read_exact_buf(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
let to_read = buf.len();
if to_read <= self.bytes.len() {
let (src, newly_remaining) = self.bytes.split_at(to_read);
self.bytes = newly_remaining;
self.current_position += to_read as u64;
buf.copy_from_slice(src);
Ok(())
} else {
Err(BytesReadError::InsufficientBytes {
expected: to_read,
actual: self.bytes.len(),
position: self.current_position,
})
}
}
}
#[cfg(not(feature = "std"))]
impl<'a> RmpRead for &'a [u8] {
type Error = BytesReadError;
fn read_u8(&mut self) -> Result<u8, Self::Error> {
if let Some((&first, newly_remaining)) = self.split_first() {
*self = newly_remaining;
Ok(first)
} else {
Err(BytesReadError::InsufficientBytes {
expected: 1,
actual: 0,
position: 0,
})
}
}
fn read_exact_buf(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
let to_read = buf.len();
if to_read <= self.len() {
let (src, newly_remaining) = self.split_at(to_read);
*self = newly_remaining;
buf.copy_from_slice(src);
Ok(())
} else {
Err(BytesReadError::InsufficientBytes {
expected: to_read,
actual: self.len(),
position: 0,
})
}
}
}