read_url/zip/
blocking.rs

1use super::{super::errors::*, zip_url::*};
2
3use {
4    rc_zip_sync::*,
5    self_cell::*,
6    std::{fs::*, io},
7};
8
9//
10// ReadZipMove
11//
12
13/// A version of [ReadZip] that takes ownership of self.
14pub trait ReadZipMove {
15    /// A version of [ReadZip::read_zip] that takes ownership of self.
16    fn read_zip_move(self) -> Result<MovableArchiveHandle, UrlError>;
17}
18
19impl ReadZipMove for File {
20    fn read_zip_move(self) -> Result<MovableArchiveHandle, UrlError> {
21        MovableArchiveHandle::new_for(self)
22    }
23}
24
25//
26// MovableArchiveHandle
27//
28
29self_cell!(
30    /// An [ArchiveHandle] that owns its [File].
31    pub struct MovableArchiveHandle {
32        owner: File,
33
34        #[covariant]
35        dependent: DependentArchiveHandle,
36    }
37);
38
39// self_cell needs a non-nested type name
40type DependentArchiveHandle<'own> = ArchiveHandle<'own, File>;
41
42impl MovableArchiveHandle {
43    /// Constructor.
44    pub fn new_for(file: File) -> Result<MovableArchiveHandle, UrlError> {
45        MovableArchiveHandle::try_new(file, |file| Ok(file.read_zip()?))
46    }
47}
48
49//
50// MovableEntryHandle
51//
52
53self_cell!(
54    /// An [EntryHandle] that owns its [MovableArchiveHandle].
55    pub struct MovableEntryHandle {
56        owner: MovableArchiveHandle,
57
58        #[covariant]
59        dependent: DependentEntryHandle,
60    }
61);
62
63// self_cell needs a non-nested type name
64type DependentEntryHandle<'own> = EntryHandle<'own, File>;
65
66impl MovableArchiveHandle {
67    /// A version of [ArchiveHandle::by_name] that returns a [MovableEntryHandle].
68    pub fn by_name(self, url: &ZipUrl) -> Result<MovableEntryHandle, UrlError> {
69        MovableEntryHandle::try_new(self, |movable_archive_handle| {
70            movable_archive_handle.borrow_dependent().by_name(&url.path).ok_or_else(|| UrlError::new_io_not_found(url))
71        })
72    }
73}
74
75//
76// MovableEntryHandleReader
77//
78
79self_cell!(
80    /// An [io::Read] that owns its [MovableEntryHandle].
81    pub struct MovableEntryHandleReader {
82        owner: MovableEntryHandle,
83
84        #[covariant]
85        dependent: DependentReader,
86    }
87);
88
89// self_cell needs a non-nested type name
90type DependentReader<'own> = Box<dyn io::Read + 'own>;
91
92impl MovableEntryHandle {
93    /// A version of [EntryHandle::reader] that returns a [MovableEntryHandleReader].
94    pub fn reader(self) -> Result<MovableEntryHandleReader, UrlError> {
95        MovableEntryHandleReader::try_new(self, |movable_entry_handle| {
96            Ok(Box::new(movable_entry_handle.borrow_dependent().reader()))
97        })
98    }
99}
100
101impl io::Read for MovableEntryHandleReader {
102    fn read(&mut self, buffer: &mut [u8]) -> io::Result<usize> {
103        self.with_dependent_mut(|_entry_handle, reader| reader.read(buffer))
104    }
105}