use std::io::Read;
use std::panic::Location;
use crate::{Error, Result};
pub trait Reader {
#[track_caller]
#[inline]
fn read_into(&mut self, buffer: &mut [u8]) -> Result<()> {
self.read_into_tracked(buffer, Location::caller())
}
fn read_into_tracked(
&mut self,
buffer: &mut [u8],
caller: &'static std::panic::Location,
) -> Result<()>;
#[track_caller]
#[inline]
fn read_as_vec(&mut self, size: usize) -> Result<Vec<u8>> {
let mut vec = vec![0u8; size];
self.read_into_tracked(vec.as_mut_slice(), Location::caller())?;
Ok(vec)
}
#[track_caller]
#[inline]
fn read_buffer_of<T: Sized, const L: usize>(&mut self) -> Result<[T; L]>
where
T: Copy + Default,
{
self.read_buffer_of_tracked::<T, L>(Location::caller())
}
#[inline]
fn read_buffer_of_tracked<T: Sized, const L: usize>(
&mut self,
caller: &'static std::panic::Location,
) -> Result<[T; L]>
where
T: Copy + Default,
{
let length = L * core::mem::size_of::<T>();
let mut buffer = [T::default(); L];
let ptr = buffer.as_mut_ptr() as *mut u8;
let slice = unsafe { std::slice::from_raw_parts_mut(ptr, length) };
self.read_into_tracked(slice, caller)?;
Ok(buffer)
}
}
impl<Base> Reader for Base
where
Base: Read + Sized,
{
#[inline]
fn read_into_tracked(
&mut self,
buffer: &mut [u8],
caller: &'static std::panic::Location,
) -> Result<()> {
match self.read_exact(buffer) {
Ok(..) => Ok(()),
Err(io) => Err(Error::ReadFailed(buffer.len(), io, caller)),
}
}
}