From 1f4eba2bcb36fa94603446d1dc29ed52127b5ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20M=2E=20Bezerra?= Date: Fri, 3 Feb 2023 02:07:49 -0300 Subject: [PATCH] separate function `check_invalid_compression_with_non_archive_format` --- src/check.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++- src/commands/mod.rs | 56 ++++++------------------------------------ 2 files changed, 65 insertions(+), 50 deletions(-) diff --git a/src/check.rs b/src/check.rs index dd5b6a0..f7d0237 100644 --- a/src/check.rs +++ b/src/check.rs @@ -3,13 +3,14 @@ #![warn(missing_docs)] use std::{ + ffi::OsString, ops::ControlFlow, path::{Path, PathBuf}, }; use crate::{ error::FinalError, - extension::Extension, + extension::{build_archive_file_suggestion, Extension}, info, utils::{pretty_format_list_of_paths, try_infer_extension, user_wants_to_continue, EscapedPathDisplay}, warning, QuestionAction, QuestionPolicy, Result, @@ -166,3 +167,59 @@ pub fn check_first_format_when_compressing<'a>(formats: &'a [Extension], output_ .into() }) } + +/// Check if compression is invalid because an archive format is necessary. +pub fn check_invalid_compression_with_non_archive_format( + formats: &[Extension], + output_path: &Path, + files: &[PathBuf], + formats_from_flag: Option<&OsString>, +) -> Result<()> { + let first_format = check_first_format_when_compressing(formats, output_path)?; + + let is_some_input_a_folder = files.iter().any(|path| path.is_dir()); + let is_multiple_inputs = files.len() > 1; + + // If first format is not archive, can't compress folder, or multiple files + if !first_format.is_archive() && (is_some_input_a_folder || is_multiple_inputs) { + let first_detail_message = if is_multiple_inputs { + "You are trying to compress multiple files." + } else { + "You are trying to compress a folder." + }; + + let (from_hint, to_hint) = if let Some(formats) = formats_from_flag { + let formats = formats.to_string_lossy(); + ( + format!("From: --format {formats}"), + format!("To: --format tar.{formats}"), + ) + } else { + // This piece of code creates a suggestion for compressing multiple files + // It says: + // Change from file.bz.xz + // To file.tar.bz.xz + let suggested_output_path = build_archive_file_suggestion(output_path, ".tar") + .expect("output path should contain a compression format"); + + ( + format!("From: {}", EscapedPathDisplay::new(output_path)), + format!("To: {suggested_output_path}"), + ) + }; + let output_path = EscapedPathDisplay::new(output_path); + + let error = FinalError::with_title(format!("Cannot compress to '{output_path}'.")) + .detail(first_detail_message) + .detail(format!( + "The compression format '{first_format}' does not accept multiple files.", + )) + .detail("Formats that bundle files into an archive are tar and zip.") + .hint(format!("Try inserting 'tar.' or 'zip.' before '{first_format}'.")) + .hint(from_hint) + .hint(to_hint); + + return Err(error.into()); + } + Ok(()) +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 2c0cdaf..483ec25 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -14,7 +14,7 @@ use crate::{ cli::Subcommand, commands::{compress::compress_files, decompress::decompress_file, list::list_archive_contents}, error::{Error, FinalError}, - extension::{self, build_archive_file_suggestion, parse_format}, + extension::{self, parse_format}, info, list::ListOptions, utils::{self, to_utf, EscapedPathDisplay, FileVisibilityPolicy}, @@ -59,54 +59,12 @@ pub fn run( None => (None, extension::extensions_from_path(&output_path)), }; - let first_format = check::check_first_format_when_compressing(&formats, &output_path)?; - - let is_some_input_a_folder = files.iter().any(|path| path.is_dir()); - let is_multiple_inputs = files.len() > 1; - - // If first format is not archive, can't compress folder, or multiple files - // Index safety: empty formats should be checked above. - if !first_format.is_archive() && (is_some_input_a_folder || is_multiple_inputs) { - let first_detail_message = if is_multiple_inputs { - "You are trying to compress multiple files." - } else { - "You are trying to compress a folder." - }; - - let (from_hint, to_hint) = if let Some(formats) = formats_from_flag { - let formats = formats.to_string_lossy(); - ( - format!("From: --format {formats}"), - format!("To: --format tar.{formats}"), - ) - } else { - // This piece of code creates a suggestion for compressing multiple files - // It says: - // Change from file.bz.xz - // To file.tar.bz.xz - let suggested_output_path = build_archive_file_suggestion(&output_path, ".tar") - .expect("output path should contain a compression format"); - - ( - format!("From: {}", EscapedPathDisplay::new(&output_path)), - format!("To: {suggested_output_path}"), - ) - }; - let output_path = EscapedPathDisplay::new(&output_path); - - let error = FinalError::with_title(format!("Cannot compress to '{output_path}'.")) - .detail(first_detail_message) - .detail(format!( - "The compression format '{first_format}' does not accept multiple files.", - )) - .detail("Formats that bundle files into an archive are tar and zip.") - .hint(format!("Try inserting 'tar.' or 'zip.' before '{first_format}'.")) - .hint(from_hint) - .hint(to_hint); - - return Err(error.into()); - } - + check::check_invalid_compression_with_non_archive_format( + &formats, + &output_path, + &files, + formats_from_flag.as_ref(), + )?; check::check_archive_formats_position(&formats, &output_path)?; let output_file = match utils::ask_to_create_file(&output_path, question_policy)? {