Description
In terms of the API of this crate, one of the simplest use cases (writing a zip file) with (admittedly not well-formatted but easily imaginable) code like this has a footgun:
fn zip_files(paths: &[PathBuf]) -> Result<Vec<u8>, ZipError> {
let mut io_cursor = Cursor::new(Vec::<u8>::new());
let mut zipwriter = zip::ZipWriter::new(&mut io_cursor);
let options = FileOptions::default().compression_method(zip::CompressionMethod::Stored);
for path in paths {
let mut buffer = vec![];
zipwriter.start_file(path.to_str().unwrap(), options)?;
let mut filehandle = std::fs::File::open(path)?;
filehandle.read_to_end(&mut buffer)?;
zipwriter.write_all(&buffer)?;
}
zipwriter.finish()?;
// Code does not compile without this
// drop(zipwriter);
Ok(io_cursor.into_inner())
}
Without an active drop(), this code does not compile, as the zipwriter keeps the exclusive reference even though it's finished.
This seems unnecessary, since using the writer after completing the zip file is explicitly not recommended behaviour anyway.
This would not be a problem if zipwriter.finish() simply consumed self, which could also drop it after finish() is completed.
This could be solved with an own scope too, but that is obviously somewhat equivalent to the active drop() invocation.
Obviously this would be a breaking change, but I imagine this could be a worthwhile improvement to the API of ZipWriter