Skip to content

Commit 95ae6fe

Browse files
committed
Accept negative Level::Precise
Fixed #179 Also, for bzip2, flate2 and zstd, use min/max level provided by the crate instead of hard-code these values into async-compression. Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
1 parent 5a6b15e commit 95ae6fe

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

src/lib.rs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@
130130
)]
131131
#![cfg_attr(not(all), allow(unused))]
132132

133+
#[cfg(any(feature = "bzip2", feature = "flate2", feature = "xz2"))]
134+
use std::convert::TryInto;
135+
133136
#[macro_use]
134137
mod macros;
135138
mod codec;
@@ -159,7 +162,7 @@ pub enum Level {
159162
/// qualities. The interpretation of this depends on the algorithm chosen
160163
/// and the specific implementation backing it.
161164
/// Qualities are implicitly clamped to the algorithm's maximum.
162-
Precise(u32),
165+
Precise(i32),
163166
}
164167

165168
impl Level {
@@ -168,7 +171,7 @@ impl Level {
168171
match self {
169172
Self::Fastest => params.quality = 0,
170173
Self::Best => params.quality = 11,
171-
Self::Precise(quality) => params.quality = quality.min(11) as i32,
174+
Self::Precise(quality) => params.quality = quality.min(11),
172175
Self::Default => (),
173176
}
174177

@@ -177,30 +180,49 @@ impl Level {
177180

178181
#[cfg(feature = "bzip2")]
179182
fn into_bzip2(self) -> bzip2::Compression {
183+
let fastest = bzip2::Compression::fast();
184+
let best = bzip2::Compression::best();
185+
180186
match self {
181-
Self::Fastest => bzip2::Compression::fast(),
182-
Self::Best => bzip2::Compression::best(),
183-
Self::Precise(quality) => bzip2::Compression::new(quality.max(1).min(9)),
187+
Self::Fastest => fastest,
188+
Self::Best => best,
189+
Self::Precise(quality) => bzip2::Compression::new(
190+
quality
191+
.try_into()
192+
.unwrap_or(0)
193+
.max(fastest.level())
194+
.min(best.level()),
195+
),
184196
Self::Default => bzip2::Compression::default(),
185197
}
186198
}
187199

188200
#[cfg(feature = "flate2")]
189201
fn into_flate2(self) -> flate2::Compression {
202+
let fastest = flate2::Compression::fast();
203+
let best = flate2::Compression::best();
204+
190205
match self {
191-
Self::Fastest => flate2::Compression::fast(),
192-
Self::Best => flate2::Compression::best(),
193-
Self::Precise(quality) => flate2::Compression::new(quality.min(10)),
206+
Self::Fastest => fastest,
207+
Self::Best => best,
208+
Self::Precise(quality) => flate2::Compression::new(
209+
quality
210+
.try_into()
211+
.unwrap_or(0)
212+
.max(fastest.level())
213+
.min(best.level()),
214+
),
194215
Self::Default => flate2::Compression::default(),
195216
}
196217
}
197218

198219
#[cfg(feature = "zstd")]
199220
fn into_zstd(self) -> i32 {
221+
let (fastest, best) = libzstd::compression_level_range().into_inner();
200222
match self {
201-
Self::Fastest => 1,
202-
Self::Best => 21,
203-
Self::Precise(quality) => quality.min(21) as i32,
223+
Self::Fastest => fastest,
224+
Self::Best => best,
225+
Self::Precise(quality) => quality.max(fastest).min(best),
204226
Self::Default => libzstd::DEFAULT_COMPRESSION_LEVEL,
205227
}
206228
}
@@ -210,7 +232,7 @@ impl Level {
210232
match self {
211233
Self::Fastest => 0,
212234
Self::Best => 9,
213-
Self::Precise(quality) => quality.min(9),
235+
Self::Precise(quality) => quality.try_into().unwrap_or(0).min(9),
214236
Self::Default => 5,
215237
}
216238
}

tests/proptest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn any_level() -> impl Strategy<Value = Level> {
1414
Just(Level::Fastest),
1515
Just(Level::Best),
1616
Just(Level::Default),
17-
any::<u32>().prop_map(Level::Precise),
17+
any::<i32>().prop_map(Level::Precise),
1818
]
1919
}
2020

tests/utils/test_cases.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ macro_rules! io_test_cases {
102102
fn with_level_max() {
103103
let encoder = bufread::Encoder::with_quality(
104104
bufread::from(&one_to_six_stream()),
105-
Level::Precise(u32::max_value()),
105+
Level::Precise(i32::max_value()),
106106
);
107107
let compressed = read::to_vec(encoder);
108108
let output = sync::decompress(&compressed);
@@ -354,7 +354,7 @@ macro_rules! io_test_cases {
354354
|input| {
355355
Box::pin(write::Encoder::with_quality(
356356
input,
357-
Level::Precise(u32::max_value()),
357+
Level::Precise(i32::max_value()),
358358
))
359359
},
360360
65_536,

0 commit comments

Comments
 (0)