read_url/zip/
asynchronous.rs

1use super::{super::errors::*, zip_url::*};
2
3use {
4    positioned_io::*,
5    rc_zip_tokio::*,
6    self_cell::*,
7    std::{pin::*, sync::*, task::*},
8    tokio::io,
9};
10
11type RandomAccessFileRef = Arc<RandomAccessFile>;
12
13//
14// AsyncReadZipMove
15//
16
17/// A version of [ReadZip] that takes ownership of self.
18pub trait AsyncReadZipMove {
19    /// A version of [ReadZip::read_zip] that takes ownership of self.
20    #[allow(async_fn_in_trait)]
21    async fn read_zip_move(self) -> Result<AsyncMovableArchiveHandle, UrlError>;
22}
23
24impl AsyncReadZipMove for Arc<RandomAccessFile> {
25    async fn read_zip_move(self) -> Result<AsyncMovableArchiveHandle, UrlError> {
26        AsyncMovableArchiveHandle::new_for(self).await
27    }
28}
29
30//
31// AsyncMovableArchiveHandle
32//
33
34self_cell!(
35    /// An [ArchiveHandle] that owns its [RandomAccessFile].
36    pub struct AsyncMovableArchiveHandle {
37        owner: RandomAccessFileRef,
38
39        #[covariant, async_builder]
40        dependent: DependentArchiveHandle,
41    }
42);
43
44// self_cell needs a non-nested type name
45type DependentArchiveHandle<'own> = ArchiveHandle<'own, RandomAccessFileRef>;
46
47impl AsyncMovableArchiveHandle {
48    /// Constructor.
49    pub async fn new_for(file: RandomAccessFileRef) -> Result<AsyncMovableArchiveHandle, UrlError> {
50        AsyncMovableArchiveHandle::try_new(file, async |file| file.read_zip().await.map_err(|error| error.into())).await
51    }
52}
53
54//
55// AsyncMovableEntryHandle
56//
57
58self_cell!(
59    /// An [EntryHandle] that owns its [AsyncMovableArchiveHandle].
60    pub struct AsyncMovableEntryHandle {
61        owner: AsyncMovableArchiveHandle,
62
63        #[covariant, async_builder]
64        dependent: DependentEntryHandle,
65    }
66);
67
68// self_cell needs a non-nested type name
69type DependentEntryHandle<'own> = EntryHandle<'own, RandomAccessFileRef>;
70
71impl AsyncMovableArchiveHandle {
72    /// A version of [ArchiveHandle::by_name] that returns a [AsyncMovableEntryHandle].
73    pub async fn by_name(self, url: &ZipUrl) -> Result<AsyncMovableEntryHandle, UrlError> {
74        AsyncMovableEntryHandle::try_new(self, async |movable_archive_handle| {
75            movable_archive_handle.borrow_dependent().by_name(&url.path).ok_or_else(|| UrlError::new_io_not_found(url))
76        })
77        .await
78    }
79}
80
81//
82// AsyncMovableEntryHandleReader
83//
84
85self_cell!(
86    /// An [io::AsyncRead] that owns its [AsyncMovableEntryHandle].
87    pub struct AsyncMovableEntryHandleReader {
88        owner: AsyncMovableEntryHandle,
89
90        #[covariant]
91        dependent: DependentReader,
92    }
93);
94
95// self_cell needs a non-nested type name
96type DependentReader<'own> = Pin<Box<dyn io::AsyncRead + 'own>>;
97
98impl AsyncMovableEntryHandle {
99    /// A version of [EntryHandle::reader] that returns an [AsyncMovableEntryHandleReader].
100    pub fn reader(self) -> Result<AsyncMovableEntryHandleReader, UrlError> {
101        AsyncMovableEntryHandleReader::try_new(self, |movable_entry_handle| {
102            Ok(Box::pin(movable_entry_handle.borrow_dependent().reader()))
103        })
104    }
105}
106
107impl io::AsyncRead for AsyncMovableEntryHandleReader {
108    fn poll_read(
109        self: Pin<&mut Self>,
110        context: &mut Context<'_>,
111        buffer: &mut io::ReadBuf<'_>,
112    ) -> Poll<io::Result<()>> {
113        self.get_mut().with_dependent_mut(|_movable_entry_handle, reader| reader.as_mut().poll_read(context, buffer))
114    }
115}