1use cyfs_base::BuckyResult;
2
3use std::path::{Path, PathBuf};
4use std::{fs, io};
5use zip::ZipArchive;
6
7pub fn extract_from_zip(zip_path: &Path, dest_path: &Path) -> BuckyResult<()> {
8    let file = fs::File::open(zip_path)?;
9    let mut archive = ZipArchive::new(file)?;
10
11    for i in 0..archive.len() {
12        let mut file = archive.by_index(i)?;
13        let mut file_path = PathBuf::from(dest_path);
14
15        #[allow(deprecated)]
16        file_path.push(file.sanitized_name());
17        if file.is_dir() {
18            fs::create_dir_all(&file_path).unwrap_or(());
19        } else {
20            if let Some(path) = file_path.parent() {
21                ensure_dir(path);
22            }
23
24            let mut out = fs::File::create(&file_path)?;
25            io::copy(&mut file, &mut out)?;
26        }
27
28        #[cfg(unix)]
30        {
31            use std::os::unix::fs::PermissionsExt;
32
33            if let Some(mode) = file.unix_mode() {
34                fs::set_permissions(&file_path, fs::Permissions::from_mode(mode)).unwrap();
35            }
36        }
37    }
38
39    return Ok(());
40}
41
42fn ensure_dir<P: AsRef<Path>>(path: P) {
43    if !path.as_ref().exists() {
44        fs::create_dir_all(path).unwrap_or(());
45    }
46}