1use std::fs;
2use std::fs::File;
3use std::io::{Read, Seek, Write};
4use std::path::Path;
5use std::str;
6
7use walkdir::{DirEntry, WalkDir};
8use zip::write::FileOptions;
9
10pub fn compress_dir(src_dir: &Path, target: &Path) {
11 let zipfile = std::fs::File::create(target).unwrap();
12 let dir = WalkDir::new(src_dir);
13 zip_dir(
14 &mut dir.into_iter().filter_map(|e| e.ok()),
15 src_dir.to_str().unwrap(),
16 zipfile,
17 )
18 .unwrap();
19}
20
21fn compress_file(src_dir: &Path, target: &Path) {
22 let zipfile = std::fs::File::create(target).unwrap();
23 let dir = WalkDir::new(src_dir);
24
25 let prefix = src_dir
27 .parent()
28 .map_or_else(|| "/", |p| p.to_str().unwrap());
29 zip_dir(&mut dir.into_iter().filter_map(|e| e.ok()), prefix, zipfile).unwrap();
30}
31
32fn zip_dir<T>(
33 it: &mut dyn Iterator<Item = DirEntry>,
34 prefix: &str,
35 writer: T,
36) -> zip::result::ZipResult<()>
37where
38 T: Write + Seek,
39{
40 let mut zip = zip::ZipWriter::new(writer);
41 let options = FileOptions::default()
42 .unix_permissions(0o755);
44
45 let mut buffer = Vec::new();
46 for entry in it {
47 let path = entry.path();
48 let name = path.strip_prefix(Path::new(prefix)).unwrap();
49 if path.is_file() {
52 println!("adding file {:?} as {:?} ...", path, name);
53 zip.start_file(name.to_string_lossy(), options)?;
54 let mut f = File::open(path)?;
55
56 f.read_to_end(&mut buffer)?;
57 zip.write_all(&*buffer)?;
58 buffer.clear();
59 } else if !name.as_os_str().is_empty() {
60 println!("adding dir {:?} as {:?} ...", path, name);
63 zip.add_directory(name.to_string_lossy(), options)?;
64 }
65 }
66 zip.finish()?;
67 Result::Ok(())
68}
69
70pub fn extract(test: &Path, target: &Path) {
71 let zipfile = std::fs::File::open(&test).unwrap();
72 let mut zip = zip::ZipArchive::new(zipfile).unwrap();
73
74 if !target.exists() {
75 fs::create_dir_all(target)
76 .map_err(|e| {
77 println!("{}", e);
78 })
79 .unwrap();
80 }
81 for i in 0..zip.len() {
82 let mut file = zip.by_index(i).unwrap();
83 println!("Filename: {} {:?}", file.name(), file.mangled_name());
84 if file.is_dir() {
85 println!("file utf8 path {:?}", file.name_raw());
86 let target = target.join(Path::new(&file.name().replace('\\', "")));
87 fs::create_dir_all(target).unwrap();
88 } else {
89 let file_path = target.join(Path::new(file.name()));
90 let mut target_file = if !file_path.exists() {
91 println!("file path {}", file_path.to_str().unwrap());
92 fs::File::create(file_path).unwrap()
93 } else {
94 fs::File::open(file_path).unwrap()
95 };
96 std::io::copy(&mut file, &mut target_file).unwrap();
97 }
99 }
100}
101
102fn create_dir(path: &Path) -> Result<(), std::io::Error> {
103 fs::create_dir_all(path)
104}