From 2c917dfa294c2c1d0ba5d37ad03fa5fda0dee284 Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Tue, 14 Mar 2023 20:07:16 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E2=9C=A8=20add=20raw=20level=20arg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cli/args.rs | 4 +++ src/commands/compress.rs | 72 +++++++++++++++++++++++++++++++++++----- src/commands/mod.rs | 1 + 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/cli/args.rs b/src/cli/args.rs index a200dc6..5183e59 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -44,6 +44,10 @@ pub struct CliArgs { /// Ouch and claps subcommands #[command(subcommand)] pub cmd: Subcommand, + + /// Compression raw level as each algo has + #[arg(short = 'r', long, global = true, default_value_t = u32::MAX)] + pub raw_level: u32, } #[derive(Parser, PartialEq, Eq, Debug)] diff --git a/src/commands/compress.rs b/src/commands/compress.rs index fb69a75..e0dee06 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -31,6 +31,7 @@ pub fn compress_files( quiet: bool, question_policy: QuestionPolicy, file_visibility_policy: FileVisibilityPolicy, + raw_level: u32, ) -> crate::Result { // If the input files contain a directory, then the total size will be underestimated let file_writer = BufWriter::with_capacity(BUFFER_CAPACITY, output_file); @@ -43,20 +44,73 @@ pub fn compress_files( Gzip => Box::new( // by default, ParCompress uses a default compression level of 3 // instead of the regular default that flate2 uses - gzp::par::compress::ParCompress::::builder() - .compression_level(Default::default()) - .from_writer(encoder), + if raw_level == u32::MAX { + gzp::par::compress::ParCompress::::builder() + .compression_level(Default::default()) + .from_writer(encoder) + } else { + gzp::par::compress::ParCompress::::builder() + .compression_level(gzp::par::compress::Compression::new(raw_level)) + .from_writer(encoder) + }, ), - Bzip => Box::new(bzip2::write::BzEncoder::new(encoder, Default::default())), - Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new(encoder, Default::default())?), - Lzma => Box::new(xz2::write::XzEncoder::new(encoder, 6)), - Snappy => Box::new(gzp::par::compress::ParCompress::::builder().from_writer(encoder)), + Bzip => { + if raw_level == u32::MAX { + Box::new(bzip2::write::BzEncoder::new(encoder, Default::default())) + } else { + Box::new(bzip2::write::BzEncoder::new( + encoder, + bzip2::Compression::new(raw_level), + )) + } + } + Lz4 => { + if raw_level == u32::MAX { + Box::new(lzzzz::lz4f::WriteCompressor::new(encoder, Default::default())?) + } else { + Box::new(lzzzz::lz4f::WriteCompressor::new( + encoder, + lzzzz::lz4f::PreferencesBuilder::new() + .compression_level(raw_level as i32) + .build(), + )?) + } + } + Lzma => { + if raw_level == u32::MAX { + Box::new(xz2::write::XzEncoder::new(encoder, 6)) + } else { + Box::new(xz2::write::XzEncoder::new(encoder, raw_level)) + } + } + Snappy => { + if raw_level == u32::MAX { + Box::new(gzp::par::compress::ParCompress::::builder().from_writer(encoder)) + } else { + Box::new( + gzp::par::compress::ParCompress::::builder() + .compression_level(gzp::par::compress::Compression::new(raw_level)) + .from_writer(encoder), + ) + } + } Zstd => { - let zstd_encoder = zstd::stream::write::Encoder::new(encoder, Default::default()); + if raw_level == u32::MAX { + Box::new( + zstd::stream::write::Encoder::new(encoder, Default::default()) + .unwrap() + .auto_finish(), + ) + } else { + Box::new( + zstd::stream::write::Encoder::new(encoder, raw_level as i32) + .unwrap() + .auto_finish(), + ) + } // Safety: // Encoder::new() can only fail if `level` is invalid, but Default::default() // is guaranteed to be valid - Box::new(zstd_encoder.unwrap().auto_finish()) } Tar | Zip => unreachable!(), }; diff --git a/src/commands/mod.rs b/src/commands/mod.rs index a96983d..d2f0eb7 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -80,6 +80,7 @@ pub fn run( args.quiet, question_policy, file_visibility_policy, + args.raw_level, ); if let Ok(true) = compress_result { From df5f846581c492a1ca821dd42b08a57b7e553f39 Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Wed, 15 Mar 2023 21:41:59 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=94=A5=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cli/args.rs | 4 +- src/commands/compress.rs | 91 +++++++++++++--------------------------- src/commands/mod.rs | 2 +- 3 files changed, 32 insertions(+), 65 deletions(-) diff --git a/src/cli/args.rs b/src/cli/args.rs index 5183e59..7cf037f 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -46,8 +46,8 @@ pub struct CliArgs { pub cmd: Subcommand, /// Compression raw level as each algo has - #[arg(short = 'r', long, global = true, default_value_t = u32::MAX)] - pub raw_level: u32, + #[arg(short = 'l', long)] + pub level: Option, } #[derive(Parser, PartialEq, Eq, Debug)] diff --git a/src/commands/compress.rs b/src/commands/compress.rs index e0dee06..44eb9b1 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -31,7 +31,7 @@ pub fn compress_files( quiet: bool, question_policy: QuestionPolicy, file_visibility_policy: FileVisibilityPolicy, - raw_level: u32, + level: Option, ) -> crate::Result { // If the input files contain a directory, then the total size will be underestimated let file_writer = BufWriter::with_capacity(BUFFER_CAPACITY, output_file); @@ -44,70 +44,37 @@ pub fn compress_files( Gzip => Box::new( // by default, ParCompress uses a default compression level of 3 // instead of the regular default that flate2 uses - if raw_level == u32::MAX { - gzp::par::compress::ParCompress::::builder() - .compression_level(Default::default()) - .from_writer(encoder) - } else { - gzp::par::compress::ParCompress::::builder() - .compression_level(gzp::par::compress::Compression::new(raw_level)) - .from_writer(encoder) - }, + gzp::par::compress::ParCompress::::builder() + .compression_level(level.map_or_else(|| Default::default(), |l| gzp::Compression::new(l as u32))) + .from_writer(encoder), ), - Bzip => { - if raw_level == u32::MAX { - Box::new(bzip2::write::BzEncoder::new(encoder, Default::default())) - } else { - Box::new(bzip2::write::BzEncoder::new( - encoder, - bzip2::Compression::new(raw_level), + Bzip => Box::new(bzip2::write::BzEncoder::new( + encoder, + level.map_or_else(|| Default::default(), |l| bzip2::Compression::new(l as u32)), + )), + Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new( + encoder, + lzzzz::lz4f::PreferencesBuilder::new() + .compression_level(level.map_or_else(|| Default::default(), |l| l as i32)) + .build(), + )?), + Lzma => Box::new(xz2::write::XzEncoder::new( + encoder, + level.map_or_else(|| Default::default(), |l| l as u32), + )), + Snappy => Box::new( + gzp::par::compress::ParCompress::::builder() + .compression_level(gzp::par::compress::Compression::new( + level.map_or_else(|| Default::default(), |l| l as u32), )) - } - } - Lz4 => { - if raw_level == u32::MAX { - Box::new(lzzzz::lz4f::WriteCompressor::new(encoder, Default::default())?) - } else { - Box::new(lzzzz::lz4f::WriteCompressor::new( - encoder, - lzzzz::lz4f::PreferencesBuilder::new() - .compression_level(raw_level as i32) - .build(), - )?) - } - } - Lzma => { - if raw_level == u32::MAX { - Box::new(xz2::write::XzEncoder::new(encoder, 6)) - } else { - Box::new(xz2::write::XzEncoder::new(encoder, raw_level)) - } - } - Snappy => { - if raw_level == u32::MAX { - Box::new(gzp::par::compress::ParCompress::::builder().from_writer(encoder)) - } else { - Box::new( - gzp::par::compress::ParCompress::::builder() - .compression_level(gzp::par::compress::Compression::new(raw_level)) - .from_writer(encoder), - ) - } - } + .from_writer(encoder), + ), Zstd => { - if raw_level == u32::MAX { - Box::new( - zstd::stream::write::Encoder::new(encoder, Default::default()) - .unwrap() - .auto_finish(), - ) - } else { - Box::new( - zstd::stream::write::Encoder::new(encoder, raw_level as i32) - .unwrap() - .auto_finish(), - ) - } + Box::new( + zstd::stream::write::Encoder::new(encoder, level.map_or_else(|| Default::default(), |l| l as i32)) + .unwrap() + .auto_finish(), + ) // Safety: // Encoder::new() can only fail if `level` is invalid, but Default::default() // is guaranteed to be valid diff --git a/src/commands/mod.rs b/src/commands/mod.rs index d2f0eb7..e45e3fe 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -80,7 +80,7 @@ pub fn run( args.quiet, question_policy, file_visibility_policy, - args.raw_level, + args.level, ); if let Ok(true) = compress_result { From ffa16c7d6e8a4967607b76750dd63cd155f909c1 Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Fri, 17 Mar 2023 17:59:53 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E2=9C=85=20add=20test,=20move?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cli/args.rs | 8 ++++---- src/commands/compress.rs | 31 ++++++++++++++++--------------- src/commands/mod.rs | 3 ++- tests/integration.rs | 20 ++++++++++++++++++++ 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/cli/args.rs b/src/cli/args.rs index 7cf037f..8e77f7f 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -44,10 +44,6 @@ pub struct CliArgs { /// Ouch and claps subcommands #[command(subcommand)] pub cmd: Subcommand, - - /// Compression raw level as each algo has - #[arg(short = 'l', long)] - pub level: Option, } #[derive(Parser, PartialEq, Eq, Debug)] @@ -63,6 +59,10 @@ pub enum Subcommand { /// The resulting file. Its extensions can be used to specify the compression formats #[arg(required = true, value_hint = ValueHint::FilePath)] output: PathBuf, + + /// Compression raw level as each algo has + #[arg(short, long)] + level: Option, }, /// Decompresses one or more files, optionally into another folder #[command(visible_alias = "d")] diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 44eb9b1..71d6e46 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -45,40 +45,41 @@ pub fn compress_files( // by default, ParCompress uses a default compression level of 3 // instead of the regular default that flate2 uses gzp::par::compress::ParCompress::::builder() - .compression_level(level.map_or_else(|| Default::default(), |l| gzp::Compression::new(l as u32))) + .compression_level(level.map_or_else(Default::default, |l| gzp::Compression::new(l as u32))) .from_writer(encoder), ), Bzip => Box::new(bzip2::write::BzEncoder::new( encoder, - level.map_or_else(|| Default::default(), |l| bzip2::Compression::new(l as u32)), + level.map_or_else(Default::default, |l| { + if l < 1 || l > 9 { + bzip2::Compression::new(1) + } else { + bzip2::Compression::new(l as u32) + } + }), )), Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new( encoder, lzzzz::lz4f::PreferencesBuilder::new() - .compression_level(level.map_or_else(|| Default::default(), |l| l as i32)) + .compression_level(level.map_or(0, |l| l as i32)) .build(), )?), Lzma => Box::new(xz2::write::XzEncoder::new( encoder, - level.map_or_else(|| Default::default(), |l| l as u32), + level.map_or(6, |l| if l < 0 || l > 9 { 6 } else { l as u32 }), )), Snappy => Box::new( gzp::par::compress::ParCompress::::builder() .compression_level(gzp::par::compress::Compression::new( - level.map_or_else(|| Default::default(), |l| l as u32), + level.map_or_else(Default::default, |l| l as u32), )) .from_writer(encoder), ), - Zstd => { - Box::new( - zstd::stream::write::Encoder::new(encoder, level.map_or_else(|| Default::default(), |l| l as i32)) - .unwrap() - .auto_finish(), - ) - // Safety: - // Encoder::new() can only fail if `level` is invalid, but Default::default() - // is guaranteed to be valid - } + Zstd => Box::new( + zstd::stream::write::Encoder::new(encoder, level.map_or(0, |l| l as i32)) + .unwrap() + .auto_finish(), + ), Tar | Zip => unreachable!(), }; Ok(encoder) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index e45e3fe..a4a3c82 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -44,6 +44,7 @@ pub fn run( Subcommand::Compress { files, output: output_path, + level, } => { // After cleaning, if there are no input files left, exit if files.is_empty() { @@ -80,7 +81,7 @@ pub fn run( args.quiet, question_policy, file_visibility_policy, - args.level, + level, ); if let Ok(true) = compress_result { diff --git a/tests/integration.rs b/tests/integration.rs index eec7a29..35832ac 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -133,3 +133,23 @@ fn multiple_files( ouch!("-A", "d", archive, "-d", after); assert_same_directory(before, after, !matches!(ext, DirectoryExtension::Zip)); } + +// compress and decompress a single file with comp levels +#[proptest(cases = 512)] +fn single_file_level( + ext: Extension, + #[any(size_range(0..8).lift())] exts: Vec, + #[strategy(-3i16..30)] level: i16, +) { + let dir = tempdir().unwrap(); + let dir = dir.path(); + let before = &dir.join("before"); + fs::create_dir(before).unwrap(); + let before_file = &before.join("file"); + let archive = &dir.join(format!("file.{}", merge_extensions(ext, exts))); + let after = &dir.join("after"); + fs::write(before_file, []).unwrap(); + ouch!("-A", "c", "-l", level.to_string(), before_file, archive); + ouch!("-A", "d", archive, "-d", after); + assert_same_directory(before, after, false); +} From d9ffd42c8fbab2cb0fabec75d210527d0e34dd5e Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Fri, 17 Mar 2023 21:36:31 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=90=9B=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/commands/compress.rs | 12 +++++------- tests/integration.rs | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 71d6e46..54eb1a2 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -45,23 +45,21 @@ pub fn compress_files( // by default, ParCompress uses a default compression level of 3 // instead of the regular default that flate2 uses gzp::par::compress::ParCompress::::builder() - .compression_level(level.map_or_else(Default::default, |l| gzp::Compression::new(l as u32))) + .compression_level(level.map_or_else(Default::default, |l| { + gzp::Compression::new(if l < 1 || l > 9 { 1 } else { l as u32 }) + })) .from_writer(encoder), ), Bzip => Box::new(bzip2::write::BzEncoder::new( encoder, level.map_or_else(Default::default, |l| { - if l < 1 || l > 9 { - bzip2::Compression::new(1) - } else { - bzip2::Compression::new(l as u32) - } + bzip2::Compression::new(if l < 1 || l > 9 { 1 } else { l as u32 }) }), )), Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new( encoder, lzzzz::lz4f::PreferencesBuilder::new() - .compression_level(level.map_or(0, |l| l as i32)) + .compression_level(level.map_or(0, |l| if l < 1 || l > 12 { 0 } else { l as i32 })) .build(), )?), Lzma => Box::new(xz2::write::XzEncoder::new( diff --git a/tests/integration.rs b/tests/integration.rs index 35832ac..428524f 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -139,7 +139,7 @@ fn multiple_files( fn single_file_level( ext: Extension, #[any(size_range(0..8).lift())] exts: Vec, - #[strategy(-3i16..30)] level: i16, + #[strategy(0i16..30)] level: i16, ) { let dir = tempdir().unwrap(); let dir = dir.path(); From 653ff976f507ae5dd1e5f448f524861155ba56a1 Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Fri, 17 Mar 2023 22:09:20 +0800 Subject: [PATCH 5/9] clamp , merge test --- Cargo.lock | 68 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/commands/compress.rs | 16 +++++----- tests/integration.rs | 28 ++++------------- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 837f7f7..1621202 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -653,6 +653,73 @@ dependencies = [ "getrandom", ] +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -706,6 +773,7 @@ dependencies = [ "libc", "linked-hash-map", "lzzzz", + "num", "once_cell", "parse-display", "proptest", diff --git a/Cargo.toml b/Cargo.toml index d7291ee..c8dff06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ ignore = "0.4.20" libc = "0.2.140" linked-hash-map = "0.5.6" lzzzz = "1.0.4" +num = "0.4.0" once_cell = "1.17.1" rayon = "1.7.0" same-file = "1.0.6" diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 54eb1a2..f8da228 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -45,36 +45,36 @@ pub fn compress_files( // by default, ParCompress uses a default compression level of 3 // instead of the regular default that flate2 uses gzp::par::compress::ParCompress::::builder() - .compression_level(level.map_or_else(Default::default, |l| { - gzp::Compression::new(if l < 1 || l > 9 { 1 } else { l as u32 }) - })) + .compression_level( + level.map_or_else(Default::default, |l| gzp::Compression::new(num::clamp(l as u32, 1, 9))), + ) .from_writer(encoder), ), Bzip => Box::new(bzip2::write::BzEncoder::new( encoder, level.map_or_else(Default::default, |l| { - bzip2::Compression::new(if l < 1 || l > 9 { 1 } else { l as u32 }) + bzip2::Compression::new(num::clamp(l as u32, 1, 9)) }), )), Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new( encoder, lzzzz::lz4f::PreferencesBuilder::new() - .compression_level(level.map_or(0, |l| if l < 1 || l > 12 { 0 } else { l as i32 })) + .compression_level(level.map_or(0, |l| num::clamp(l as i32, 1, 12))) .build(), )?), Lzma => Box::new(xz2::write::XzEncoder::new( encoder, - level.map_or(6, |l| if l < 0 || l > 9 { 6 } else { l as u32 }), + level.map_or(6, |l| num::clamp(l as u32, 0, 9)), )), Snappy => Box::new( gzp::par::compress::ParCompress::::builder() .compression_level(gzp::par::compress::Compression::new( - level.map_or_else(Default::default, |l| l as u32), + level.map_or_else(Default::default, |l| num::clamp(l as u32, 0, 9)), )) .from_writer(encoder), ), Zstd => Box::new( - zstd::stream::write::Encoder::new(encoder, level.map_or(0, |l| l as i32)) + zstd::stream::write::Encoder::new(encoder, level.map_or(0, |l| num::clamp(l as i32, 1, 22))) .unwrap() .auto_finish(), ), diff --git a/tests/integration.rs b/tests/integration.rs index 428524f..4b1d518 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -100,7 +100,11 @@ fn single_empty_file(ext: Extension, #[any(size_range(0..8).lift())] exts: Vec) { +fn single_file( + ext: Extension, + #[any(size_range(0..8).lift())] exts: Vec, + #[strategy(0i16..30)] level: i16, +) { let dir = tempdir().unwrap(); let dir = dir.path(); let before = &dir.join("before"); @@ -109,7 +113,7 @@ fn single_file(ext: Extension, #[any(size_range(0..8).lift())] exts: Vec, - #[strategy(0i16..30)] level: i16, -) { - let dir = tempdir().unwrap(); - let dir = dir.path(); - let before = &dir.join("before"); - fs::create_dir(before).unwrap(); - let before_file = &before.join("file"); - let archive = &dir.join(format!("file.{}", merge_extensions(ext, exts))); - let after = &dir.join("after"); - fs::write(before_file, []).unwrap(); - ouch!("-A", "c", "-l", level.to_string(), before_file, archive); - ouch!("-A", "d", archive, "-d", after); - assert_same_directory(before, after, false); -} From b8b9c5042fe81206865afe823ddd3c5208c4b61c Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Sat, 18 Mar 2023 08:54:15 +0800 Subject: [PATCH 6/9] :bug: fix --- Cargo.lock | 68 ---------------------------------------- Cargo.toml | 1 - src/commands/compress.rs | 23 ++++++++------ 3 files changed, 13 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1621202..837f7f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -653,73 +653,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "num" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -773,7 +706,6 @@ dependencies = [ "libc", "linked-hash-map", "lzzzz", - "num", "once_cell", "parse-display", "proptest", diff --git a/Cargo.toml b/Cargo.toml index c8dff06..d7291ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ ignore = "0.4.20" libc = "0.2.140" linked-hash-map = "0.5.6" lzzzz = "1.0.4" -num = "0.4.0" once_cell = "1.17.1" rayon = "1.7.0" same-file = "1.0.6" diff --git a/src/commands/compress.rs b/src/commands/compress.rs index f8da228..6d941ac 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -46,37 +46,40 @@ pub fn compress_files( // instead of the regular default that flate2 uses gzp::par::compress::ParCompress::::builder() .compression_level( - level.map_or_else(Default::default, |l| gzp::Compression::new(num::clamp(l as u32, 1, 9))), + level.map_or_else(Default::default, |l| gzp::Compression::new((l as u32).clamp(0, 9))), ) .from_writer(encoder), ), Bzip => Box::new(bzip2::write::BzEncoder::new( encoder, - level.map_or_else(Default::default, |l| { - bzip2::Compression::new(num::clamp(l as u32, 1, 9)) - }), + level.map_or_else(Default::default, |l| bzip2::Compression::new((l as u32).clamp(1, 9))), )), Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new( encoder, lzzzz::lz4f::PreferencesBuilder::new() - .compression_level(level.map_or(0, |l| num::clamp(l as i32, 1, 12))) + .compression_level(level.map_or(0, |l| (l as i32).clamp(1, lzzzz::lz4f::CLEVEL_MAX))) .build(), )?), Lzma => Box::new(xz2::write::XzEncoder::new( encoder, - level.map_or(6, |l| num::clamp(l as u32, 0, 9)), + level.map_or(6, |l| (l as u32).clamp(0, 9)), )), Snappy => Box::new( gzp::par::compress::ParCompress::::builder() .compression_level(gzp::par::compress::Compression::new( - level.map_or_else(Default::default, |l| num::clamp(l as u32, 0, 9)), + level.map_or_else(Default::default, |l| (l as u32).clamp(0, 9)), )) .from_writer(encoder), ), Zstd => Box::new( - zstd::stream::write::Encoder::new(encoder, level.map_or(0, |l| num::clamp(l as i32, 1, 22))) - .unwrap() - .auto_finish(), + zstd::stream::write::Encoder::new( + encoder, + level.map_or(0, |l| { + (l as i32).clamp(zstd::zstd_safe::min_c_level(), zstd::zstd_safe::max_c_level()) + }), + ) + .unwrap() + .auto_finish(), ), Tar | Zip => unreachable!(), }; From e92b9ff723c5c3f1c73ab866e1a945964800f9f4 Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Sat, 18 Mar 2023 12:23:59 +0800 Subject: [PATCH 7/9] option level tests --- src/cli/args.rs | 2 +- src/commands/compress.rs | 18 ++++++++++-------- tests/integration.rs | 8 ++++++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/cli/args.rs b/src/cli/args.rs index 8e77f7f..1de90be 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -60,7 +60,7 @@ pub enum Subcommand { #[arg(required = true, value_hint = ValueHint::FilePath)] output: PathBuf, - /// Compression raw level as each algo has + /// Compression level, applied to all formats #[arg(short, long)] level: Option, }, diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 6d941ac..5fc5caa 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -57,7 +57,7 @@ pub fn compress_files( Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new( encoder, lzzzz::lz4f::PreferencesBuilder::new() - .compression_level(level.map_or(0, |l| (l as i32).clamp(1, lzzzz::lz4f::CLEVEL_MAX))) + .compression_level(level.map_or(1, |l| (l as i32).clamp(1, lzzzz::lz4f::CLEVEL_MAX))) .build(), )?), Lzma => Box::new(xz2::write::XzEncoder::new( @@ -71,16 +71,18 @@ pub fn compress_files( )) .from_writer(encoder), ), - Zstd => Box::new( - zstd::stream::write::Encoder::new( + Zstd => { + let zstd_encoder = zstd::stream::write::Encoder::new( encoder, - level.map_or(0, |l| { + level.map_or(zstd::DEFAULT_COMPRESSION_LEVEL, |l| { (l as i32).clamp(zstd::zstd_safe::min_c_level(), zstd::zstd_safe::max_c_level()) }), - ) - .unwrap() - .auto_finish(), - ), + ); + // Safety: + // Encoder::new() can only fail if `level` is invalid, but Default::default() + // is guaranteed to be valid + Box::new(zstd_encoder.unwrap().auto_finish()) + } Tar | Zip => unreachable!(), }; Ok(encoder) diff --git a/tests/integration.rs b/tests/integration.rs index 4b1d518..5242cff 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -103,7 +103,7 @@ fn single_empty_file(ext: Extension, #[any(size_range(0..8).lift())] exts: Vec, - #[strategy(0i16..30)] level: i16, + #[strategy(proptest::option::of(0i16..30))] level: Option, ) { let dir = tempdir().unwrap(); let dir = dir.path(); @@ -113,7 +113,11 @@ fn single_file( let archive = &dir.join(format!("file.{}", merge_extensions(ext, exts))); let after = &dir.join("after"); fs::write(before_file, []).unwrap(); - ouch!("-A", "c", "-l", level.to_string(), before_file, archive); + if let Some(level) = level { + ouch!("-A", "c", "-l", level.to_string(), before_file, archive); + } else { + ouch!("-A", "c", before_file, archive); + } ouch!("-A", "d", archive, "-d", after); assert_same_directory(before, after, false); } From 994a9b384d7b55ef94431155bda09fe547427b4e Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Sun, 19 Mar 2023 09:17:42 +0800 Subject: [PATCH 8/9] Update src/commands/compress.rs Co-authored-by: figsoda --- src/commands/compress.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 5fc5caa..353d81f 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -79,8 +79,8 @@ pub fn compress_files( }), ); // Safety: - // Encoder::new() can only fail if `level` is invalid, but Default::default() - // is guaranteed to be valid + // Encoder::new() can only fail if `level` is invalid, but the level + // is `clamp`ed and therefore guaranteed to be valid Box::new(zstd_encoder.unwrap().auto_finish()) } Tar | Zip => unreachable!(), From abc3bfe3a481d5bad7c1b66558f63bc45088897f Mon Sep 17 00:00:00 2001 From: xgdgsc Date: Sun, 19 Mar 2023 09:41:39 +0800 Subject: [PATCH 9/9] clippy fix --- src/commands/compress.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 353d81f..a2a5018 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -23,6 +23,7 @@ use crate::{ /// # Return value /// - Returns `Ok(true)` if compressed all files normally. /// - Returns `Ok(false)` if user opted to abort compression mid-way. +#[allow(clippy::too_many_arguments)] pub fn compress_files( files: Vec, extensions: Vec,