use std::{
any::Any,
fs::File,
io::{self, Cursor, Read, Seek, SeekFrom},
};
pub trait ReadSeek {
fn as_read_mut(&mut self) -> &mut dyn Read;
fn as_seek_mut(&mut self) -> &mut dyn Seek;
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<T> ReadSeek for T
where
T: Read + Seek + Any,
{
fn as_read_mut(&mut self) -> &mut dyn Read {
self
}
fn as_seek_mut(&mut self) -> &mut dyn Seek {
self
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
#[non_exhaustive]
pub enum Body {
Empty,
File(File),
Data(Cursor<Vec<u8>>),
Static(Cursor<&'static [u8]>),
Other(Box<dyn ReadSeek>),
}
impl Read for Body {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
match self {
Body::Empty => io::empty().read(buf),
Body::File(file) => file.read(buf),
Body::Data(data) => data.read(buf),
Body::Static(data) => data.read(buf),
Body::Other(other) => other.as_read_mut().read(buf),
}
}
}
impl Seek for Body {
fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
match self {
Body::Empty => io::empty().seek(pos),
Body::File(file) => file.seek(pos),
Body::Data(data) => data.seek(pos),
Body::Static(data) => data.seek(pos),
Body::Other(other) => other.as_seek_mut().seek(pos),
}
}
}