use std::fs::File;
use std::io::{Cursor, Error as IOError, Seek, Write};
use std::path::Path;
use zip::result::ZipError;
use zip::write::FileOptions;
use zip::{CompressionMethod, ZipWriter};
#[allow(dead_code)]
pub(crate) struct ZipOut<W: Write + Seek> {
zip: ZipWriter<W>,
compression: CompressionMethod,
}
pub(crate) struct ZipWrite<'a, W: Write + Seek> {
write: &'a mut ZipWriter<W>,
}
#[allow(dead_code)]
impl<W: Write + Seek> ZipOut<W> {
pub(crate) fn new_file(zip_file: &Path) -> Result<ZipOut<File>, std::io::Error> {
let f = File::create(zip_file)?;
Ok(ZipOut {
zip: ZipWriter::new(f),
compression: CompressionMethod::Deflated,
})
}
pub(crate) fn new_buf(buf: Vec<u8>) -> Result<ZipOut<Cursor<Vec<u8>>>, std::io::Error> {
Ok(ZipOut {
zip: ZipWriter::new(Cursor::new(buf)),
compression: CompressionMethod::Deflated,
})
}
pub(crate) fn new_buf_uncompressed(
buf: Vec<u8>,
) -> Result<ZipOut<Cursor<Vec<u8>>>, std::io::Error> {
Ok(ZipOut {
zip: ZipWriter::new(Cursor::new(buf)),
compression: CompressionMethod::Stored,
})
}
pub(crate) fn add_directory<S: Into<String>>(
&mut self,
path: S,
options: FileOptions,
) -> Result<(), ZipError> {
self.zip.add_directory(path, options)
}
pub(crate) fn start_file<S: Into<String>>(
&mut self,
name: S,
options: FileOptions,
) -> Result<ZipWrite<'_, W>, ZipError> {
let options = options.compression_method(self.compression);
self.zip.start_file(name, options)?;
Ok(ZipWrite {
write: &mut self.zip,
})
}
pub(crate) fn zip(mut self) -> Result<W, ZipError> {
self.zip.finish()
}
}
impl<W: Write + Seek> Write for ZipWrite<'_, W> {
fn write(&mut self, buf: &[u8]) -> Result<usize, IOError> {
self.write.write(buf)
}
fn flush(&mut self) -> Result<(), IOError> {
self.write.flush()
}
}