use super::{super::errors::*, zip_url::*};
use {
rc_zip_sync::*,
self_cell::*,
std::{fs::*, io},
};
pub trait ReadZipMove {
fn read_zip_move(self) -> Result<MovableArchiveHandle, UrlError>;
}
impl ReadZipMove for File {
fn read_zip_move(self) -> Result<MovableArchiveHandle, UrlError> {
MovableArchiveHandle::new_for(self)
}
}
self_cell!(
pub struct MovableArchiveHandle {
owner: File,
#[covariant]
dependent: DependentArchiveHandle,
}
);
type DependentArchiveHandle<'own> = ArchiveHandle<'own, File>;
impl MovableArchiveHandle {
pub fn new_for(file: File) -> Result<MovableArchiveHandle, UrlError> {
MovableArchiveHandle::try_new(file, |file| Ok(file.read_zip()?))
}
}
self_cell!(
pub struct MovableEntryHandle {
owner: MovableArchiveHandle,
#[covariant]
dependent: DependentEntryHandle,
}
);
type DependentEntryHandle<'own> = EntryHandle<'own, File>;
impl MovableArchiveHandle {
pub fn by_name(self, url: &ZipUrl) -> Result<MovableEntryHandle, UrlError> {
MovableEntryHandle::try_new(self, |movable_archive_handle| {
movable_archive_handle.borrow_dependent().by_name(&url.path).ok_or_else(|| UrlError::new_io_not_found(url))
})
}
}
self_cell!(
pub struct MovableEntryHandleReader {
owner: MovableEntryHandle,
#[covariant]
dependent: DependentReader,
}
);
type DependentReader<'own> = Box<dyn io::Read + 'own>;
impl MovableEntryHandle {
pub fn reader(self) -> Result<MovableEntryHandleReader, UrlError> {
MovableEntryHandleReader::try_new(self, |movable_entry_handle| {
Ok(Box::new(movable_entry_handle.borrow_dependent().reader()))
})
}
}
impl io::Read for MovableEntryHandleReader {
fn read(&mut self, buffer: &mut [u8]) -> io::Result<usize> {
self.with_dependent_mut(|_entry_handle, reader| reader.read(buffer))
}
}