From b093277a857bce8f8b3c4638f022876d9a0825c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Rodrigues=20Miguel?= Date: Wed, 6 Oct 2021 16:23:19 -0300 Subject: [PATCH] Refactor `FinalError::display_and_crash` into Error::Custom --- src/commands.rs | 27 +++++++++++++++------------ src/error.rs | 28 +++++++++++++++------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 355bf02..098d5a2 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -20,6 +20,7 @@ use crate::{ }, info, oof, utils, utils::to_utf, + Error, }; // Used in BufReader and BufWriter to perform less syscalls @@ -32,14 +33,16 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> { let formats = extension::extensions_from_path(&output_path); if formats.is_empty() { - FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) + let reason = FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) .detail("You shall supply the compression format via the extension.") .hint("Try adding something like .tar.gz or .zip to the output file.") .hint("") .hint("Examples:") .hint(format!(" ouch compress ... {}.tar.gz", to_utf(&output_path))) .hint(format!(" ouch compress ... {}.zip", to_utf(&output_path))) - .display_and_crash(); + .into_owned(); + + return Err(Error::with_reason(reason)); } if matches!(&formats[0], Bzip | Gzip | Lzma) && files.len() > 1 { @@ -59,35 +62,35 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> { let mut suggested_output_path = output_path.clone(); suggested_output_path.replace_range(empty_range, ".tar"); - FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) + let reason = FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) .detail("You are trying to compress multiple files.") .detail(format!("The compression format '{}' cannot receive multiple files.", &formats[0])) .detail("The only supported formats that bundle files into an archive are .tar and .zip.") .hint(format!("Try inserting '.tar' or '.zip' before '{}'.", &formats[0])) .hint(format!("From: {}", output_path)) .hint(format!(" To : {}", suggested_output_path)) - .display_and_crash(); + .into_owned(); + + return Err(Error::with_reason(reason)); } if let Some(format) = formats.iter().skip(1).position(|format| matches!(format, Tar | Zip)) { - FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) + let reason = FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) .detail(format!("Found the format '{}' in an incorrect position.", format)) .detail(format!("{} can only be used at the start of the file extension.", format)) .hint(format!("If you wish to compress multiple files, start the extension with {}.", format)) .hint(format!("Otherwise, remove {} from '{}'.", format, to_utf(&output_path))) - .display_and_crash(); + .into_owned(); + + return Err(Error::with_reason(reason)); } if output_path.exists() && !utils::user_wants_to_overwrite(&output_path, flags)? { + // User does not want to overwrite this file return Ok(()); } - let output_file = fs::File::create(&output_path).unwrap_or_else(|err| { - FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) - .detail(format!("Could not open file '{}' for writing.", to_utf(&output_path))) - .detail(format!("Error: {}.", err)) - .display_and_crash() - }); + let output_file = fs::File::create(&output_path)?; let compress_result = compress_files(files, formats, output_file, flags); // If any error occurred, delete incomplete file diff --git a/src/error.rs b/src/error.rs index 45beaae..8c4f33c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -30,11 +30,12 @@ pub enum Error { MissingArgumentsForDecompression, CompressionTypo, WalkdirError { reason: String }, + Custom { reason: FinalError }, } pub type Result = std::result::Result; -#[derive(Default)] +#[derive(Debug, Default, PartialEq)] pub struct FinalError { title: String, details: Vec, @@ -79,14 +80,9 @@ impl FinalError { self } - pub fn to_owned(&mut self) -> Self { + pub fn into_owned(&mut self) -> Self { std::mem::take(self) } - - pub fn display_and_crash(&self) -> ! { - eprintln!("{}", self); - std::process::exit(crate::EXIT_FAILURE) - } } impl fmt::Display for Error { @@ -97,7 +93,7 @@ impl fmt::Display for Error { .detail("Ouch could not detect the compression format") .hint("Use a supported format extension, like '.zip' or '.tar.gz'") .hint("Check https://github.com/vrmiguel/ouch for a full list of supported formats") - .to_owned(); + .into_owned(); error } @@ -115,7 +111,7 @@ impl fmt::Display for Error { let error = FinalError::with_title("It seems you're trying to compress the root folder.") .detail("This is unadvisable since ouch does compressions in-memory.") .hint("Use a more appropriate tool for this, such as rsync.") - .to_owned(); + .into_owned(); error } @@ -127,7 +123,7 @@ impl fmt::Display for Error { .hint(" - The output argument.") .hint("") .hint("Example: `ouch compress image.png img.zip`") - .to_owned(); + .into_owned(); error } @@ -138,7 +134,7 @@ impl fmt::Display for Error { .hint(" - At least one input argument.") .hint("") .hint("Example: `ouch decompress imgs.tar.gz`") - .to_owned(); + .into_owned(); error } @@ -148,7 +144,7 @@ impl fmt::Display for Error { .detail("It's probably our fault") .detail("Please help us improve by reporting the issue at:") .detail(format!(" {}https://github.com/vrmiguel/ouch/issues ", cyan())) - .to_owned(); + .into_owned(); error } @@ -156,7 +152,7 @@ impl fmt::Display for Error { Error::IoError { reason } => FinalError::with_title(reason), Error::CompressionTypo => FinalError::with_title("Possible typo detected") .hint(format!("Did you mean '{}ouch compress{}'?", magenta(), reset())) - .to_owned(), + .into_owned(), _err => { todo!(); } @@ -166,6 +162,12 @@ impl fmt::Display for Error { } } +impl Error { + pub fn with_reason(reason: FinalError) -> Self { + Self::Custom { reason } + } +} + impl From for Error { fn from(err: std::io::Error) -> Self { match err.kind() {