Skip to main content

zip_dir/
lib.rs

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}