use std::fs::File;
use std::io::Error;
use std::path::Path;
use zip::ZipArchive;
pub fn unzip(archive: &Path, dir: &Path) -> Result<(), Error> {
let file = File::open(archive)?;
let mut archive = ZipArchive::new(file)?;
for i in 0..archive.len() {
let mut file = archive.by_index(i)?;
let outpath = dir.join(file.sanitized_name());
if (&*file.name()).ends_with('/') {
println!("File {} extracted to \"{}\"", i, outpath.display());
std::fs::create_dir_all(&outpath)?;
} else {
println!(
"File {} extracted to \"{}\" ({} bytes)",
i,
outpath.display(),
file.size()
);
if let Some(p) = outpath.parent() {
if !p.exists() {
std::fs::create_dir_all(&p)?;
}
}
let mut outfile = std::fs::File::create(&outpath)?;
std::io::copy(&mut file, &mut outfile).unwrap();
#[cfg(unix)]
{
use std::fs::Permissions;
use std::os::unix::fs::PermissionsExt;
if let Some(mode) = file.unix_mode() {
std::fs::set_permissions(&outpath, Permissions::from_mode(mode))?;
}
}
}
}
Ok(())
}