use super::{super::errors::*, zip_url::*};
use {
positioned_io::*,
rc_zip_tokio::*,
self_cell::*,
std::{pin::*, sync::*, task::*},
tokio::io,
};
type RandomAccessFileRef = Arc<RandomAccessFile>;
pub trait AsyncReadZipMove {
#[allow(async_fn_in_trait)]
async fn read_zip_move(self) -> Result<AsyncMovableArchiveHandle, UrlError>;
}
impl AsyncReadZipMove for Arc<RandomAccessFile> {
async fn read_zip_move(self) -> Result<AsyncMovableArchiveHandle, UrlError> {
AsyncMovableArchiveHandle::new_for(self).await
}
}
self_cell!(
pub struct AsyncMovableArchiveHandle {
owner: RandomAccessFileRef,
#[covariant, async_builder]
dependent: DependentArchiveHandle,
}
);
type DependentArchiveHandle<'own> = ArchiveHandle<'own, RandomAccessFileRef>;
impl AsyncMovableArchiveHandle {
pub async fn new_for(file: RandomAccessFileRef) -> Result<AsyncMovableArchiveHandle, UrlError> {
AsyncMovableArchiveHandle::try_new(file, async |file| file.read_zip().await.map_err(|error| error.into())).await
}
}
self_cell!(
pub struct AsyncMovableEntryHandle {
owner: AsyncMovableArchiveHandle,
#[covariant, async_builder]
dependent: DependentEntryHandle,
}
);
type DependentEntryHandle<'own> = EntryHandle<'own, RandomAccessFileRef>;
impl AsyncMovableArchiveHandle {
pub async fn by_name(self, url: &ZipUrl) -> Result<AsyncMovableEntryHandle, UrlError> {
AsyncMovableEntryHandle::try_new(self, async |movable_archive_handle| {
movable_archive_handle.borrow_dependent().by_name(&url.path).ok_or_else(|| UrlError::new_io_not_found(url))
})
.await
}
}
self_cell!(
pub struct AsyncMovableEntryHandleReader {
owner: AsyncMovableEntryHandle,
#[covariant]
dependent: DependentReader,
}
);
type DependentReader<'own> = Pin<Box<dyn io::AsyncRead + 'own>>;
impl AsyncMovableEntryHandle {
pub fn reader(self) -> Result<AsyncMovableEntryHandleReader, UrlError> {
AsyncMovableEntryHandleReader::try_new(self, |movable_entry_handle| {
Ok(Box::pin(movable_entry_handle.borrow_dependent().reader()))
})
}
}
impl io::AsyncRead for AsyncMovableEntryHandleReader {
fn poll_read(
self: Pin<&mut Self>,
context: &mut Context<'_>,
buffer: &mut io::ReadBuf<'_>,
) -> Poll<io::Result<()>> {
self.get_mut().with_dependent_mut(|_movable_entry_handle, reader| reader.as_mut().poll_read(context, buffer))
}
}