refactor: improve code formatting in `mod.rs` and `logger.rs`
[ouch.git] / src / archive / rar.rs
blobc223192a4dd94b21c02955aab97b221f7c3068a5
1 //! Contains RAR-specific building and unpacking functions
3 use std::path::Path;
5 use unrar::Archive;
7 use crate::{
8     error::{Error, Result},
9     list::FileInArchive,
10     utils::logger::info,
13 /// Unpacks the archive given by `archive_path` into the folder given by `output_folder`.
14 /// Assumes that output_folder is empty
15 pub fn unpack_archive(
16     archive_path: &Path,
17     output_folder: &Path,
18     password: Option<&[u8]>,
19     quiet: bool,
20 ) -> crate::Result<usize> {
21     assert!(output_folder.read_dir().expect("dir exists").count() == 0);
23     let archive = match password {
24         Some(password) => Archive::with_password(archive_path, password),
25         None => Archive::new(archive_path),
26     };
28     let mut archive = archive.open_for_processing()?;
29     let mut unpacked = 0;
31     while let Some(header) = archive.read_header()? {
32         let entry = header.entry();
33         archive = if entry.is_file() {
34             if !quiet {
35                 info(format!(
36                     "{} extracted. ({})",
37                     entry.filename.display(),
38                     entry.unpacked_size
39                 ));
40             }
41             unpacked += 1;
42             header.extract_with_base(output_folder)?
43         } else {
44             header.skip()?
45         };
46     }
48     Ok(unpacked)
51 /// List contents of `archive_path`, returning a vector of archive entries
52 pub fn list_archive(
53     archive_path: &Path,
54     password: Option<&[u8]>,
55 ) -> Result<impl Iterator<Item = Result<FileInArchive>>> {
56     let archive = match password {
57         Some(password) => Archive::with_password(archive_path, password),
58         None => Archive::new(archive_path),
59     };
61     Ok(archive.open_for_listing()?.map(|item| {
62         let item = item?;
63         let is_dir = item.is_directory();
64         let path = item.filename;
66         Ok(FileInArchive { path, is_dir })
67     }))
70 pub fn no_compression() -> Error {
71     Error::UnsupportedFormat {
72         reason: "Creating RAR archives is not allowed due to licensing restrictions.".into(),
73     }