diff --git a/src/commands.rs b/src/commands.rs index f403c8b04..20a4f45d1 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -24,7 +24,7 @@ use crate::{ progress::Progress, utils::{ self, concatenate_os_str_list, dir_is_empty, nice_directory_display, to_utf, try_infer_extension, - user_wants_to_continue_decompressing, + user_wants_to_continue_compressing, user_wants_to_continue_decompressing, }, warning, Opts, QuestionPolicy, Subcommand, }; @@ -157,7 +157,7 @@ pub fn run(args: Opts, question_policy: QuestionPolicy) -> crate::Result<()> { formats = new_formats; } } - let compress_result = compress_files(files, formats, output_file); + let compress_result = compress_files(files, formats, output_file, &output_path, question_policy); // If any error occurred, delete incomplete file if compress_result.is_err() { @@ -268,7 +268,7 @@ pub fn run(args: Opts, question_policy: QuestionPolicy) -> crate::Result<()> { println!(); } let formats = formats.iter().flat_map(Extension::iter).map(Clone::clone).collect(); - list_archive_contents(archive_path, formats, list_options)?; + list_archive_contents(archive_path, formats, list_options, question_policy)?; } } } @@ -280,7 +280,13 @@ pub fn run(args: Opts, question_policy: QuestionPolicy) -> crate::Result<()> { // files are the list of paths to be compressed: ["dir/file1.txt", "dir/file2.txt"] // formats contains each format necessary for compression, example: [Tar, Gz] (in compression order) // output_file is the resulting compressed file name, example: "compressed.tar.gz" -fn compress_files(files: Vec, formats: Vec, output_file: fs::File) -> crate::Result<()> { +fn compress_files( + files: Vec, + formats: Vec, + output_file: fs::File, + output_dir: &Path, + question_policy: QuestionPolicy, +) -> crate::Result<()> { // The next lines are for displaying the progress bar // If the input files contain a directory, then the total size will be underestimated let (total_input_size, precise) = files @@ -347,14 +353,17 @@ fn compress_files(files: Vec, formats: Vec, output_file: fs: writer.flush()?; } 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!("{orange}[WARNING]{reset}", orange = *colors::ORANGE, reset = *colors::RESET); eprintln!( - "\tThis is a limitation for formats like '{}'.", - formats.iter().map(|format| format.to_string()).collect::() + "\tThere is a limitation for .zip archives with extra extensions. (e.g. .zip.gz)\ + \n\tThe design of .zip makes it impossible to compress via stream, so it must be done entirely in memory.\ + \n\tBy compressing .zip with extra compression formats, you can run out of RAM if the file is too large!" ); - eprintln!("\tThe design of .zip makes it impossible to compress via stream."); + + // give user the option to continue compressing after warning is shown + if !user_wants_to_continue_compressing(output_dir, question_policy)? { + return Ok(()); + } let mut vec_buffer = io::Cursor::new(vec![]); @@ -505,12 +514,17 @@ fn decompress_file( }; } Zip => { - eprintln!("Compressing first into .zip."); - eprintln!("Warning: .zip archives with extra extensions have a downside."); + eprintln!("{orange}[WARNING]{reset}", orange = *colors::ORANGE, reset = *colors::RESET); eprintln!( - "The only way is loading everything into the RAM while compressing, and then write everything down." + "\tThere is a limitation for .zip archives with extra extensions. (e.g. .zip.gz)\ + \n\tThe design of .zip makes it impossible to compress via stream, so it must be done entirely in memory.\ + \n\tBy compressing .zip with extra compression formats, you can run out of RAM if the file is too large!" ); - eprintln!("this means that by compressing .zip with extra compression formats, you can run out of RAM if the file is too large!"); + + // give user the option to continue decompressing after warning is shown + if !user_wants_to_continue_decompressing(input_file_path, question_policy)? { + return Ok(()); + } let mut vec = vec![]; io::copy(&mut reader, &mut vec)?; @@ -552,6 +566,7 @@ fn list_archive_contents( archive_path: &Path, formats: Vec, list_options: ListOptions, + question_policy: QuestionPolicy, ) -> crate::Result<()> { let reader = fs::File::open(&archive_path)?; @@ -593,10 +608,17 @@ fn list_archive_contents( let files = match formats[0] { Tar => crate::archive::tar::list_archive(reader)?, Zip => { - eprintln!("Listing files from zip archive."); - eprintln!("Warning: .zip archives with extra extensions have a downside."); - eprintln!("The only way is loading everything into the RAM while compressing, and then reading the archive contents."); - eprintln!("this means that by compressing .zip with extra compression formats, you can run out of RAM if the file is too large!"); + eprintln!("{orange}[WARNING]{reset}", orange = *colors::ORANGE, reset = *colors::RESET); + eprintln!( + "\tThere is a limitation for .zip archives with extra extensions. (e.g. .zip.gz)\ + \n\tThe design of .zip makes it impossible to compress via stream, so it must be done entirely in memory.\ + \n\tBy compressing .zip with extra compression formats, you can run out of RAM if the file is too large!" + ); + + // give user the option to continue decompressing after warning is shown + if !user_wants_to_continue_decompressing(archive_path, question_policy)? { + return Ok(()); + } let mut vec = vec![]; io::copy(&mut reader, &mut vec)?; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 4c09cd588..d7b7aadcb 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -11,7 +11,8 @@ mod question; pub use formatting::{concatenate_os_str_list, nice_directory_display, strip_cur_dir, to_utf, Bytes}; pub use fs::{cd_into_same_dir_as, clear_path, create_dir_if_non_existent, dir_is_empty, try_infer_extension}; pub use question::{ - create_or_ask_overwrite, user_wants_to_continue_decompressing, user_wants_to_overwrite, QuestionPolicy, + create_or_ask_overwrite, user_wants_to_continue_compressing, user_wants_to_continue_decompressing, + user_wants_to_overwrite, QuestionPolicy, }; pub use utf8::{get_invalid_utf8_paths, is_invalid_utf8}; diff --git a/src/utils/question.rs b/src/utils/question.rs index 67094d59f..e0d2cd51a 100644 --- a/src/utils/question.rs +++ b/src/utils/question.rs @@ -63,6 +63,20 @@ pub fn create_or_ask_overwrite(path: &Path, question_policy: QuestionPolicy) -> } } +/// Check if QuestionPolicy flags were set, otherwise, ask the user if they want to continue compressing. +pub fn user_wants_to_continue_compressing(path: &Path, question_policy: QuestionPolicy) -> crate::Result { + match question_policy { + QuestionPolicy::AlwaysYes => Ok(true), + QuestionPolicy::AlwaysNo => Ok(false), + QuestionPolicy::Ask => { + let path = to_utf(strip_cur_dir(path)); + let path = Some(path.as_str()); + let placeholder = Some("FILE"); + Confirmation::new("Do you want to continue compressing 'FILE'?", placeholder).ask(path) + } + } +} + /// Check if QuestionPolicy flags were set, otherwise, ask the user if they want to continue decompressing. pub fn user_wants_to_continue_decompressing(path: &Path, question_policy: QuestionPolicy) -> crate::Result { match question_policy {