zipsign_api/
sign_unsign_zip.rs1use std::io::{BufReader, BufWriter, Read, Seek, Write};
2
3use zip::result::ZipError;
4use zip::{ZipArchive, ZipWriter};
5
6#[derive(Debug, thiserror::Error)]
7pub(crate) enum CopyZipError {
8 #[error("could not read input ZIP")]
9 InputZip(#[source] ZipError),
10 #[error("could not read file #{1} inside input ZIP")]
11 InputZipIndex(#[source] ZipError, usize),
12 #[error("could not write to output")]
13 OutputWrite(#[source] std::io::Error),
14 #[error("could not write ZIP file #{1} to output")]
15 OutputZip(#[source] ZipError, usize),
16 #[error("could not finish writing output ZIP")]
17 OutputZipFinish(#[source] ZipError),
18}
19
20pub(crate) fn copy_zip<I, O>(input: &mut I, output: &mut O) -> Result<(), CopyZipError>
21where
22 I: ?Sized + Seek + Read,
23 O: ?Sized + Seek + Write,
24{
25 let mut input = ZipArchive::new(BufReader::new(input)).map_err(CopyZipError::InputZip)?;
26 let mut output = ZipWriter::new(BufWriter::new(output));
27
28 output.set_raw_comment(input.comment().into());
29 for idx in 0..input.len() {
30 let file = input
31 .by_index_raw(idx)
32 .map_err(|err| CopyZipError::InputZipIndex(err, idx))?;
33 output
34 .raw_copy_file(file)
35 .map_err(|err| CopyZipError::OutputZip(err, idx))?;
36 }
37 output
38 .finish()
39 .map_err(CopyZipError::OutputZipFinish)?
40 .flush()
41 .map_err(CopyZipError::OutputWrite)?;
42
43 Ok(())
44}