use core::{
error::Error,
fmt::{self, Display},
};
#[cfg(feature = "std")]
use std::io;
#[derive(Debug, PartialEq, Eq)]
pub enum ReadError {
EndOfStream,
UnknownError,
}
impl Error for ReadError {}
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 Read for &[u8] {
fn read(&mut self, buffer: &mut [u8]) -> Result<usize, ReadError> {
let len_copy = self.len().min(buffer.len());
let (read, rest) = self.split_at(len_copy);
buffer[..len_copy].copy_from_slice(read);
*self = rest;
Ok(len_copy)
}
}