Laziness of ZipArchive and ZiipFile make for an awkward API #344
Replies: 9 comments
-
I think we should be able to solve the first issue with better naming: building a There are a few options for a more intuitive API. I've been mocking up some alternatives, but they're basically all internal iterators. We'll probably end up with something like this: for line in archive.flat_map(|file| Ok(if file.name.extension() == "log" {
Some(io::BufReader::new(file).lines())
} else {
None
})) {
println!("{}", line);
} When it's eventually stabilized, we should definitely take the opportunity to implement |
Beta Was this translation helpful? Give feedback.
-
Ran into this when implementing vfs-zip, since vfs filesystems take
Writers are harder - despite the existence of write_at, I assume we can't precalculate the length of a file write until compressed, which makes writing multiple files simultaniously a nonstarter.
Some iterators can take |
Beta Was this translation helpful? Give feedback.
-
What we can do while writing is reserve a specific compressed length, and then prevent the user from writing past it. It'll just be difficult to write generically without using locks. We do have the option of simply implementing If we're being clever anyway (like that The final option worth considering is a totally custom set of traits - |
Beta Was this translation helpful? Give feedback.
-
I'm quite new to Rust, how can I use both for name in zip.file_names().map(|s| s.to_string()).collect::<Vec<_>>() {
zip.by_name(name);
} But indeed it looks quite ugly. Perhaps a |
Beta Was this translation helpful? Give feedback.
-
@fer22f The |
Beta Was this translation helpful? Give feedback.
-
Ah yes, using indexes, you're right. I will use that instead. But I still wish we could do the same with strings directly, I use a |
Beta Was this translation helpful? Give feedback.
-
Just for reference, it's looking like the new API will allow iteration like this: for file in zip.iter().filter(|file| file.name().to_str().filter(condition).is_some()) {
// use `file`
} However, I'm still not sure how a consuming iterator could work. // notice the `&`
for file in Archive::open(&File::open(path)?)? {
// move path and metadata out of `file`
} |
Beta Was this translation helpful? Give feedback.
-
I'm interested in the iterator API as well. I saw the discussion in #232 - but does the planned development includes this feature? Would you mind sharing its status? (btw thanks for the work put into this crate!) |
Beta Was this translation helpful? Give feedback.
-
It's not much, but I'll say the status on everything here is "WIP" :D I'd really love to see a more decoupled API, and it's still on the horizon. I'm going to work with zamazan on smoothing out 0.6 before any of that |
Beta Was this translation helpful? Give feedback.
-
Both
ZipArchive
andZipFile
are lazy, and only read from the underlying Reader when they absolutely have to. This is great for performance as zip archives can be very large, and we don't want to eagerly uncompress and read everything into memory. However, there are a few ways this makes the API a bit awkward:ZipArchive::{by_name,by_index}
take&mut self
This is because these methods mutate the underlying reader. Ultimately this is not an ease fix as the laziness of both
ZipArchive
andZipFile
do not really allow us to change this to&self
by using interior mutability (through use of something likeRefCell
). Most of the time having exclusive access of the ZipArchive is not an issue, but it can be confusing for newcomers who may not understand why the ZipArchive needs mutable/exclusive access for reading files.Iterator APIs are not supported
Currently the ZipArchive does not support iterators, requiring the user to get files by name or by index. Supporting iteration is not that easy as
iter()
normally takes&self
and yieldingZipFile
s from the iterator causes lifetime issues sinceZipFile
s are attached to the lifetime of the underlying reader.Question: what should we do about this? Can we keep the performance of the current API without some of these awkward parts?
Beta Was this translation helpful? Give feedback.
All reactions