Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use std::{
error::Error,
io::{
prelude::*,
Write,
},
iter::Iterator,
result::Result,
};
use zip::{
result::ZipError,
write::FileOptions,
CompressionMethod,
ZipWriter,
};
use std::{
fs::File,
path::{
Path,
PathBuf,
},
};
use walkdir::WalkDir;
const DEFAULT_UNIX_PERMISSIONS: u32 = 0o755;
fn main() {
let src_dir = PathBuf::from("./template");
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR should be set by cargo");
let dst_file = Path::new(&out_dir).join("template.zip");
match zip_dir(&src_dir, &dst_file, CompressionMethod::Stored) {
Ok(_) => {
println!(
"done: {} written to {}",
src_dir.display(),
dst_file.display()
)
}
Err(e) => eprintln!("Error: {:?}", e),
};
}
fn zip_dir(
src_dir: &PathBuf,
dst_file: &PathBuf,
method: CompressionMethod,
) -> Result<(), Box<Error>> {
if !src_dir.is_dir() {
return Err(ZipError::FileNotFound.into())
}
let file = File::create(dst_file)?;
let walkdir = WalkDir::new(src_dir);
let it = walkdir.into_iter().filter_map(|e| e.ok());
let mut zip = ZipWriter::new(file);
let options = FileOptions::default()
.compression_method(method)
.unix_permissions(DEFAULT_UNIX_PERMISSIONS);
let mut buffer = Vec::new();
for entry in it {
let path = entry.path();
let name = path.strip_prefix(&src_dir)?;
if path.is_file() {
zip.start_file_from_path(name, options)?;
let mut f = File::open(path)?;
f.read_to_end(&mut buffer)?;
zip.write_all(&*buffer)?;
buffer.clear();
} else if name.as_os_str().len() != 0 {
zip.add_directory_from_path(name, options)?;
}
}
zip.finish()?;
Ok(())
}