use std::path::Path;
use unrar::Archive;
use crate::{
error::{Error, Result},
info,
list::FileInArchive,
utils::BytesFmt,
};
pub fn unpack_archive(archive_path: &Path, output_folder: &Path, password: Option<&[u8]>) -> Result<u64> {
let archive = match password {
Some(password) => Archive::with_password(archive_path, password),
None => Archive::new(archive_path),
};
let mut archive = archive.open_for_processing()?;
let mut files_unpacked = 0;
while let Some(header) = archive.read_header()? {
let entry = header.entry();
archive = if entry.is_file() {
info!(
"extracted ({}) {}",
BytesFmt(entry.unpacked_size),
entry.filename.display(),
);
files_unpacked += 1;
header.extract_with_base(output_folder)?
} else {
header.skip()?
};
}
Ok(files_unpacked)
}
pub fn list_archive(
archive_path: &Path,
password: Option<&[u8]>,
) -> Result<impl Iterator<Item = Result<FileInArchive>> + use<>> {
let archive = match password {
Some(password) => Archive::with_password(archive_path, password),
None => Archive::new(archive_path),
};
Ok(archive.open_for_listing()?.map(|item| {
let item = item?;
let is_dir = item.is_directory();
let path = item.filename;
Ok(FileInArchive { path, is_dir })
}))
}
pub fn no_compression() -> Error {
Error::UnsupportedFormat {
reason: "Creating RAR archives is not allowed due to licensing restrictions.".into(),
}
}