use crate::{error::MapError, Error, Result};
use std::{io::Read, ops::DerefMut};
pub trait Reader<'de> {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()>;
fn can_borrow() -> bool;
fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]>;
}
impl<'de, R: ?Sized + Reader<'de>, P: DerefMut<Target = R>> Reader<'de> for P {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
self.deref_mut().read_exact(buf)
}
fn can_borrow() -> bool {
R::can_borrow()
}
fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]> {
self.deref_mut().borrow_bytes(len)
}
}
pub struct ReadAdapter<R>(R);
impl<R> ReadAdapter<R> {
pub fn new(read: R) -> Self {
Self(read)
}
}
impl<'de, R: Read> Reader<'de> for ReadAdapter<R> {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
self.0.read_exact(buf).map_error()
}
fn can_borrow() -> bool {
false
}
fn borrow_bytes(&mut self, _len: usize) -> Result<&'de [u8]> {
Err(Error::NotSupported("borrowing from a ReadAdapter"))
}
}
pub struct SliceAdapter<'a>(&'a [u8]);
impl<'a> SliceAdapter<'a> {
pub fn new(slice: &'a [u8]) -> Self {
Self(slice)
}
fn assert_longer_than(&self, buf_len: usize) -> Result<()> {
if self.0.len() >= buf_len {
Ok(())
} else {
Err(Error::Eof)
}
}
}
impl<'de> Reader<'de> for SliceAdapter<'de> {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
let buf_len = buf.len();
self.assert_longer_than(buf_len)?;
buf.copy_from_slice(&self.0[..buf_len]);
self.0 = &self.0[buf_len..];
Ok(())
}
fn can_borrow() -> bool {
true
}
fn borrow_bytes(&mut self, len: usize) -> Result<&'de [u8]> {
self.assert_longer_than(len)?;
let borrow = &self.0[..len];
self.0 = &self.0[len..];
Ok(borrow)
}
}