use crate::stable_with_metadata_of::WithMetadataOf;
use std::{
any::Any,
io::{BufRead, Read, Seek},
};
pub struct Reader<R> {
inner: R,
read: *mut dyn Read,
vtable: OptTable,
}
#[derive(Clone, Copy)]
struct OptTable {
seek: Option<*mut dyn Seek>,
buf: Option<*mut dyn BufRead>,
any: Option<*mut dyn Any>,
}
pub struct ReaderMut<'lt> {
inner: &'lt mut dyn Read,
vtable: OptTable,
}
pub struct ReaderBox<'lt> {
inner: Box<dyn Read + 'lt>,
vtable: OptTable,
}
impl<R: Read> Reader<R> {
pub fn new(mut reader: R) -> Self {
let read = lifetime_erase_trait_vtable!((&mut reader): '_ as Read);
Reader {
inner: reader,
read,
vtable: OptTable {
seek: None,
buf: None,
any: None,
},
}
}
}
impl<R> Reader<R> {
pub fn get_ref(&self) -> &R {
&self.inner
}
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
pub fn as_mut(&mut self) -> ReaderMut<'_> {
let Reader {
inner: _,
read: _,
vtable,
} = *self;
ReaderMut {
inner: self.as_read_mut(),
vtable,
}
}
pub fn into_boxed<'lt>(self) -> ReaderBox<'lt>
where
R: 'lt,
{
let Reader {
inner,
read,
vtable,
} = self;
let ptr = Box::into_raw(Box::new(inner));
let ptr = WithMetadataOf::with_metadata_of_on_stable(ptr, read);
let inner = unsafe { Box::from_raw(ptr) };
ReaderBox { inner, vtable }
}
pub fn set_buf(&mut self)
where
R: BufRead,
{
self.vtable.buf = Some(lifetime_erase_trait_vtable!((&mut self.inner): '_ as BufRead));
}
pub fn set_seek(&mut self)
where
R: Seek,
{
self.vtable.seek = Some(lifetime_erase_trait_vtable!((&mut self.inner): '_ as Seek));
}
pub fn set_any(&mut self)
where
R: Any,
{
self.vtable.any = Some(lifetime_erase_trait_vtable!((&mut self.inner): '_ as Any));
}
}
impl<R> Reader<R> {
pub fn as_read(&self) -> &(dyn Read + '_) {
let ptr = &self.inner as *const R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.read);
unsafe { &*local }
}
pub fn as_read_mut(&mut self) -> &mut (dyn Read + '_) {
let ptr = &mut self.inner as *mut R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.read);
unsafe { &mut *local }
}
pub fn as_buf(&self) -> Option<&(dyn BufRead + '_)> {
let ptr = &self.inner as *const R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
Some(unsafe { &*local })
}
pub fn as_buf_mut(&mut self) -> Option<&mut (dyn BufRead + '_)> {
let ptr = &mut self.inner as *mut R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
Some(unsafe { &mut *local })
}
pub fn as_seek(&self) -> Option<&(dyn Seek + '_)> {
let ptr = &self.inner as *const R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
Some(unsafe { &*local })
}
pub fn as_seek_mut(&mut self) -> Option<&mut (dyn Seek + '_)> {
let ptr = &mut self.inner as *mut R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
Some(unsafe { &mut *local })
}
pub fn as_any(&self) -> Option<&'_ dyn Any> {
let ptr = &self.inner as *const R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
Some(unsafe { &*local })
}
pub fn as_any_mut(&mut self) -> Option<&'_ mut dyn Any> {
let ptr = &mut self.inner as *mut R;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
Some(unsafe { &mut *local })
}
pub fn into_inner(self) -> R {
self.inner
}
}
impl ReaderMut<'_> {
pub fn as_read_mut(&mut self) -> &mut (dyn Read + '_) {
&mut *self.inner
}
pub fn as_buf_mut(&mut self) -> Option<&mut (dyn BufRead + '_)> {
let ptr = self.inner as *mut dyn Read;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
Some(unsafe { &mut *local })
}
pub fn as_seek_mut(&mut self) -> Option<&mut (dyn Seek + '_)> {
let ptr = self.inner as *mut dyn Read;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
Some(unsafe { &mut *local })
}
pub fn as_any(&self) -> Option<&'_ dyn Any> {
let ptr = self.inner as *const dyn Read;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
Some(unsafe { &*local })
}
pub fn as_any_mut(&mut self) -> Option<&'_ mut dyn Any> {
let ptr = self.inner as *mut dyn Read;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
Some(unsafe { &mut *local })
}
}
impl ReaderBox<'_> {
pub fn as_mut(&mut self) -> ReaderMut<'_> {
ReaderMut {
vtable: self.vtable,
inner: self.as_read_mut(),
}
}
pub fn as_read_mut(&mut self) -> &mut (dyn Read + '_) {
&mut *self.inner
}
pub fn as_buf_mut(&mut self) -> Option<&mut (dyn BufRead + '_)> {
let ptr = self.inner.as_mut() as *mut _;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
Some(unsafe { &mut *local })
}
pub fn as_seek_mut(&mut self) -> Option<&mut (dyn Seek + '_)> {
let ptr = self.inner.as_mut() as *mut _;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
Some(unsafe { &mut *local })
}
pub fn as_any(&self) -> Option<&'_ dyn Any> {
let ptr = self.inner.as_ref() as *const _;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
Some(unsafe { &*local })
}
pub fn as_any_mut(&mut self) -> Option<&'_ mut dyn Any> {
let ptr = self.inner.as_mut() as *mut _;
let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
Some(unsafe { &mut *local })
}
}
impl<'lt, R> From<&'lt mut Reader<R>> for ReaderMut<'lt> {
fn from(value: &'lt mut Reader<R>) -> Self {
value.as_mut()
}
}
impl<'lt, R: 'lt> From<Reader<R>> for ReaderBox<'lt> {
fn from(value: Reader<R>) -> Self {
value.into_boxed()
}
}
impl<'lt> From<&'lt mut ReaderBox<'_>> for ReaderMut<'lt> {
fn from(value: &'lt mut ReaderBox<'_>) -> Self {
value.as_mut()
}
}