1use std::fs::{read_dir, DirEntry, File};
2use std::io::{self, Read, Seek, Write};
3use std::path::Path;
4
5use zip::result::ZipResult;
6use zip::write::FileOptions;
7use zip::CompressionMethod;
8use zip::ZipWriter;
9
10pub fn zip_dir<T: Write + Seek>(
11 path: &Path,
12 target: T,
13 options: Option<FileOptions>,
14) -> ZipResult<T> {
15 let mut zip = ZipWriter::new(target);
16
17 let options =
18 options.unwrap_or(FileOptions::default().compression_method(CompressionMethod::Stored));
19
20 for entry in read_dir(path)? {
21 zip_entry(&mut zip, entry?, options)?;
22 }
23
24 zip.finish()
25}
26
27fn zip_entry<T: Write + Seek>(
28 zip: &mut ZipWriter<T>,
29 entry: DirEntry,
30 options: FileOptions,
31) -> io::Result<()> {
32 let path = entry.path();
33
34 if path.is_dir() {
35 for entry in read_dir(path)? {
36 zip_entry(zip, entry?, options)?;
37 }
38 } else {
39 zip.start_file_from_path(&path, options)?;
40
41 let mut file = File::open(path)?;
42 let mut buffer = Vec::new();
43
44 file.read_to_end(&mut buffer)?;
45
46 zip.write(&buffer)?;
47 }
48
49 Ok(())
50}