-
Notifications
You must be signed in to change notification settings - Fork 204
WIP: API Design #156
Comments
There's also the possibility of supporting concurrent/parallel archives. We'd need to use custom traits in the place of
|
I would also like us to address #147 |
There's another option which might be able to give the user more control: If we could just emit owned let source = File::open("orig.zip")?;
let mut out = zip::Archive::create(File::create("new.zip")?);
zip::headers(source.try_clone()?)
.par_iter()
.try_for_each_init(
|| source.try_clone().unwrap(),
|source, r| r.and_then(|header| match header.last_modified().elapsed() {
// the file was last modified in the last hour
Ok(dur) if dur < Duration::from_secs(60 * 60) => header.copy(source, out),
// This `copy` method would have to be magic to actually work
_ => Ok(()),
},
))?; EDIT: I believe this addresses the concerns brought up in #147 - is there any particular use case you'd like to improve? |
I'm worried that this API, while powerful, will be tough to use. |
We should be able to draw from #91 to improve the parser's startup time (It should be constant for the archives without comments) I don't think there's any way to avoid parsing the files in order, since the names and comments have a variable length, but I imagine it's common not to need to parse the whole central directory |
TimeWhen working with time, we'd ideally be able to state the moment in time at which something happened. In the case of ZIP files, we want to know when a file was added to the archive. Unfortunately, ZIP files' There are a few ZIP extensions which provide alternatives:
It's possible for the parser to encounter any combination of these, so we'll need to be able to resolve conflicts:
|
|
Ooh... I've run into a real problem with the ergonomics of the file API. So, I'd like to provide something along the lines of the API in the original post: impl<S: io::Write> Archive<S> {
pub fn insert(&mut self, path: PathBuf) -> io::Result<File<&mut S>>;
}
io::copy(&mut file, &mut archive.insert(file.path())?)?; But this API is impossible to implement. At least, without a panicking branch in The user can "fix" the issue like so: let mut zip_file = archive.insert(file.path())?;
io::copy(&mut file, &mut zip_file)?;
zip_file.finalize(); // consumes `zip_file` ...once they've already experienced a crash because they wrote their code the easy, incorrect way. Tbh I'm stuck on this one. Aha! Thinking back to the current design, we could have the |
@rylev Do you have an opinion on #156 (comment) ? |
@Plecra what's the reason for allowing separate writes for both a path and the contents? Wouldn't it make more sense to force the user to provide the path and the contents at the same time? |
I'm not sure I understand. Do you mean an API like |
I didn't necessarily mean taking an owned buffer, but yes in general, I meant taking a concrete type that represents the contents that we want to write. I understand that allowing writing to an |
What part of the API do you consider awkward? It's about the same as Since we'll be writing to a generic writer anyway, it seems reasonable to reflect that API ourselves. I mean, we write the file contents through |
This is all still relevant, but will continue development elsewhere (currently in 0.7/0.10 branches) |
After sifting through the specification and the issues left in the repository, I've mocked up what I think would be a good API to work towards. It's incomplete, and I mostly bring it up as food for better ideas. Anyway, goals...
Examples
Normalization
Feeding files through the library lets it strip unnecessary data from the archive, and recompress the files where appropriate. This also gives it a chance to adjust the
version needed to extract
down.fn Archive::rebuild<W: io::Write>(&mut self, sink: W, filter: impl FnMut(&File) -> bool);
Cons
Edit: I've created the 0.7 branch to explorer the API redesign. We can make proposals as PRs to it
The text was updated successfully, but these errors were encountered: