use core::{fmt, fmt::Display};
#[cfg(feature = "std")]
use std::io;
#[derive(Debug, PartialEq, Eq)]
pub enum ReadError {
EndOfStream,
UnknownError,
}
impl Display for ReadError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ReadError::EndOfStream => write!(f, "encountered unexpected end of stream"),
ReadError::UnknownError => write!(f, "encountered unknown error"),
}
}
}
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, ReadError>;
}
#[cfg(feature = "std")]
impl<T> Read for T
where
T: io::Read,
{
fn read(&mut self, buffer: &mut [u8]) -> Result<usize, ReadError> {
<T as io::Read>::read(self, buffer).map_err(|error| match error.kind() {
io::ErrorKind::UnexpectedEof => ReadError::EndOfStream,
_ => ReadError::UnknownError,
})
}
}
#[cfg(not(feature = "std"))]
impl<'a> Read for &'a [u8] {
fn read(&mut self, buffer: &mut [u8]) -> Result<usize, ReadError> {
let len_copy = self.len().min(buffer.len());
buffer[..len_copy].copy_from_slice(&self[..len_copy]);
*self = &self[len_copy..];
Ok(len_copy)
}
}