build_script/
dirzip.rs

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    // src_dir.parent().map( |p| println!("{:?}",p.to_str().unwrap()));
26    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        // .compression_method(zip::CompressionMethod::Bzip2)
43        .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        // Write file or directory explicitly
50        // Some unzip tools unzip files with directory paths correctly, some do not!
51        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            // Only if not root! Avoids path spec / warning
61            // and mapname conversion failed error on unzip
62            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            // target_file.write_all(file.read_bytes().into());
98        }
99    }
100}
101
102fn create_dir(path: &Path) -> Result<(), std::io::Error> {
103    fs::create_dir_all(path)
104}