diff --git a/src/archive/zip.rs b/src/archive/zip.rs index 32257772e..be47ea8cf 100644 --- a/src/archive/zip.rs +++ b/src/archive/zip.rs @@ -11,7 +11,7 @@ use zip::{self, read::ZipFile, ZipArchive}; use crate::{ info, oof, - utils::{self, Bytes}, + utils::{self, dir_is_empty, Bytes}, }; use self::utf8::get_invalid_utf8_paths; @@ -93,7 +93,7 @@ where info!("Compressing '{}'.", utils::to_utf(path)); if path.is_dir() { - if dir_is_empty(path)? { + if dir_is_empty(path) { writer.add_directory(path.to_str().unwrap().to_owned(), options)?; } // If a dir has files, the files are responsible for creating them. @@ -119,10 +119,6 @@ fn check_for_comments(file: &ZipFile) { } } -fn dir_is_empty(dir_path: &Path) -> crate::Result { - Ok(dir_path.read_dir()?.next().is_none()) -} - #[cfg(unix)] fn __unix_set_permissions(file_path: &Path, file: &ZipFile) -> crate::Result<()> { use std::os::unix::fs::PermissionsExt; diff --git a/src/commands.rs b/src/commands.rs index 9086bb68c..bf278b61b 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -18,14 +18,25 @@ use crate::{ self, CompressionFormat::{self, *}, }, - info, oof, utils, + info, oof, utils::to_utf, + utils::{self, dir_is_empty}, Error, }; // Used in BufReader and BufWriter to perform less syscalls const BUFFER_CAPACITY: usize = 1024 * 64; +fn represents_several_files(files: &[PathBuf]) -> bool { + let is_non_empty_dir = |path: &PathBuf| { + let is_non_empty = || !dir_is_empty(&path); + + path.is_dir().then(is_non_empty).unwrap_or_default() + }; + + files.iter().any(is_non_empty_dir) || files.len() > 1 +} + pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> { match command { Command::Compress { files, output_path } => { @@ -45,7 +56,7 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> { return Err(Error::with_reason(reason)); } - if matches!(&formats[0], Bzip | Gzip | Lzma) && files.len() > 1 { + if matches!(&formats[0], Bzip | Gzip | Lzma) && represents_several_files(&files) { // This piece of code creates a sugestion for compressing multiple files // It says: // Change from file.bz.xz @@ -205,7 +216,7 @@ fn compress_files( Zip => { eprintln!("{yellow}Warning:{reset}", yellow = colors::yellow(), reset = colors::reset()); eprintln!("\tCompressing .zip entirely in memory."); - eprintln!("\tIf the file is too big, your pc might freeze!"); + eprintln!("\tIf the file is too big, your PC might freeze!"); eprintln!( "\tThis is a limitation for formats like '{}'.", formats.iter().map(|format| format.to_string()).collect::() diff --git a/src/error.rs b/src/error.rs index 8c4f33c4c..3792bfb8f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -35,7 +35,7 @@ pub enum Error { pub type Result = std::result::Result; -#[derive(Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq)] pub struct FinalError { title: String, details: Vec, @@ -153,9 +153,12 @@ impl fmt::Display for Error { Error::CompressionTypo => FinalError::with_title("Possible typo detected") .hint(format!("Did you mean '{}ouch compress{}'?", magenta(), reset())) .into_owned(), - _err => { - todo!(); - } + Error::UnknownExtensionError(_) => todo!(), + Error::AlreadyExists => todo!(), + Error::InvalidZipArchive(_) => todo!(), + Error::PermissionDenied => todo!(), + Error::UnsupportedZipArchive(_) => todo!(), + Error::Custom { reason } => reason.clone(), }; write!(f, "{}", err) diff --git a/src/utils.rs b/src/utils.rs index a56220d25..a03d22735 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,12 +1,19 @@ use std::{ cmp, env, ffi::OsStr, - fs, + fs::{self, ReadDir}, path::{Path, PathBuf}, }; use crate::{dialogs::Confirmation, info, oof}; +/// Checks if the given path represents an empty directory. +pub fn dir_is_empty(dir_path: &Path) -> bool { + let is_empty = |mut rd: ReadDir| rd.next().is_none(); + + dir_path.read_dir().ok().map(is_empty).unwrap_or_default() +} + pub fn create_dir_if_non_existent(path: &Path) -> crate::Result<()> { if !path.exists() { fs::create_dir_all(path)?;