From 19769223c8d1faadf96e62edbfb154910b356219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20M=2E=20Bezerra?= Date: Sat, 4 Jun 2022 12:55:51 -0300 Subject: [PATCH] create helper function `split_first_extension` --- src/commands/compress.rs | 9 ++++++--- src/commands/decompress.rs | 12 ++++++++---- src/extension.rs | 7 +++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 3f7bbdb..3969509 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -9,6 +9,7 @@ use crate::{ archive, commands::warn_user_about_in_memory_zip_compression, extension::{ + split_first_extension, CompressionFormat::{self, *}, Extension, }, @@ -69,11 +70,13 @@ pub fn compress_files( Ok(encoder) }; - for format in formats.iter().flat_map(Extension::iter).skip(1).collect::>().iter().rev() { + let (first_extension, extensions) = split_first_extension(&formats); + + for format in extensions.iter().rev() { writer = chain_writer_encoder(format, writer)?; } - match formats[0].compression_formats[0] { + match first_extension { Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => { let _progress = Progress::new_accessible_aware( total_input_size, @@ -81,7 +84,7 @@ pub fn compress_files( Some(Box::new(move || output_file_path.metadata().expect("file exists").len())), ); - writer = chain_writer_encoder(&formats[0].compression_formats[0], writer)?; + writer = chain_writer_encoder(&first_extension, writer)?; let mut reader = fs::File::open(&files[0]).unwrap(); io::copy(&mut reader, &mut writer)?; } diff --git a/src/commands/decompress.rs b/src/commands/decompress.rs index aa297f9..82bd5c4 100644 --- a/src/commands/decompress.rs +++ b/src/commands/decompress.rs @@ -9,6 +9,7 @@ use fs_err as fs; use crate::{ commands::warn_user_about_in_memory_zip_decompression, extension::{ + split_first_extension, CompressionFormat::{self, *}, Extension, }, @@ -34,6 +35,7 @@ pub fn decompress_file( assert!(output_dir.exists()); let total_input_size = input_file_path.metadata().expect("file exists").len(); let reader = fs::File::open(&input_file_path)?; + // Zip archives are special, because they require io::Seek, so it requires it's logic separated // from decoder chaining. // @@ -41,7 +43,7 @@ pub fn decompress_file( // in-memory decompression/copying first. // // Any other Zip decompression done can take up the whole RAM and freeze ouch. - if formats.len() == 1 && *formats[0].compression_formats == [Zip] { + if let [Extension { compression_formats: [Zip], .. }] = formats.as_slice() { let zip_archive = zip::ZipArchive::new(reader)?; let files = if let ControlFlow::Continue(files) = smart_unpack( Box::new(move |output_dir| { @@ -93,13 +95,15 @@ pub fn decompress_file( Ok(decoder) }; - for format in formats.iter().flat_map(Extension::iter).skip(1).collect::>().iter().rev() { + let (first_extension, extensions) = split_first_extension(&formats); + + for format in extensions.iter().rev() { reader = chain_reader_decoder(format, reader)?; } - let files_unpacked = match formats[0].compression_formats[0] { + let files_unpacked = match first_extension { Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => { - reader = chain_reader_decoder(&formats[0].compression_formats[0], reader)?; + reader = chain_reader_decoder(&first_extension, reader)?; let writer = utils::create_or_ask_overwrite(&output_file_path, question_policy)?; if writer.is_none() { diff --git a/src/extension.rs b/src/extension.rs index 77ace4b..580599c 100644 --- a/src/extension.rs +++ b/src/extension.rs @@ -171,3 +171,10 @@ mod tests { assert_eq!(formats, vec![&Tar, &Gzip]); } } + +// Panics if formats has an empty list of compression formats +pub fn split_first_extension(formats: &[Extension]) -> (CompressionFormat, Vec) { + let mut extensions: Vec = formats.iter().flat_map(Extension::iter).copied().collect(); + let first_extension = extensions.remove(0); + (first_extension, extensions) +}