1#![allow(unexpected_cfgs)]
33#![cfg_attr(
34 feature = "futures-io",
35 doc = "[`futures-io`] | [`futures::io::AsyncBufRead`](futures_io::AsyncBufRead), [`futures::io::AsyncWrite`](futures_io::AsyncWrite)"
36)]
37#![cfg_attr(
38 not(feature = "futures-io"),
39 doc = "`futures-io` (*inactive*) | `futures::io::AsyncBufRead`, `futures::io::AsyncWrite`"
40)]
41#![cfg_attr(
42 feature = "tokio",
43 doc = "[`tokio`] | [`tokio::io::AsyncBufRead`](::tokio::io::AsyncBufRead), [`tokio::io::AsyncWrite`](::tokio::io::AsyncWrite)"
44)]
45#![cfg_attr(
46 not(feature = "tokio"),
47 doc = "`tokio` (*inactive*) | `tokio::io::AsyncBufRead`, `tokio::io::AsyncWrite`"
48)]
49#, [`BrotliDecoder`](?search=BrotliDecoder)"
62)]
63#![cfg_attr(
64 not(feature = "brotli"),
65 doc = "`brotli` (*inactive*) | `BrotliEncoder`, `BrotliDecoder`"
66)]
67#, [`BzDecoder`](?search=BzDecoder)"
70)]
71#![cfg_attr(
72 not(feature = "bzip2"),
73 doc = "`bzip2` (*inactive*) | `BzEncoder`, `BzDecoder`"
74)]
75#, [`DeflateDecoder`](?search=DeflateDecoder)"
78)]
79#![cfg_attr(
80 not(feature = "deflate"),
81 doc = "`deflate` (*inactive*) | `DeflateEncoder`, `DeflateDecoder`"
82)]
83#, [`GzipDecoder`](?search=GzipDecoder)"
86)]
87#![cfg_attr(
88 not(feature = "gzip"),
89 doc = "`gzip` (*inactive*) | `GzipEncoder`, `GzipDecoder`"
90)]
91#, [`Lz4Decoder`](?search=Lz4Decoder)"
94)]
95#![cfg_attr(
96 not(feature = "lz4"),
97 doc = "`lz4` (*inactive*) | `Lz4Encoder`, `Lz4Decoder`"
98)]
99#, [`LzmaDecoder`](?search=LzmaDecoder)"
102)]
103#![cfg_attr(
104 not(feature = "lzma"),
105 doc = "`lzma` (*inactive*) | `LzmaEncoder`, `LzmaDecoder`"
106)]
107#, [`XzDecoder`](?search=XzDecoder)"
110)]
111#![cfg_attr(
112 not(feature = "xz"),
113 doc = "`xz` (*inactive*) | `XzEncoder`, `XzDecoder`"
114)]
115#, [`ZlibDecoder`](?search=ZlibDecoder)"
118)]
119#![cfg_attr(
120 not(feature = "zlib"),
121 doc = "`zlib` (*inactive*) | `ZlibEncoder`, `ZlibDecoder`"
122)]
123#, [`ZstdDecoder`](?search=ZstdDecoder)"
126)]
127#![cfg_attr(
128 not(feature = "zstd"),
129 doc = "`zstd` (*inactive*) | `ZstdEncoder`, `ZstdDecoder`"
130)]
131#"
134)]
135#![cfg_attr(
136 not(feature = "deflate64"),
137 doc = "`deflate64` (*inactive*) | (encoder not implemented), `Deflate64Decoder`"
138)]
139#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
147#![warn(
148 missing_docs,
149 rust_2018_idioms,
150 missing_copy_implementations,
151 missing_debug_implementations
152)]
153#![cfg_attr(not(all), allow(unused))]
154
155#[cfg(any(
156 feature = "bzip2",
157 feature = "flate2",
158 feature = "lzma",
159 feature = "lz4"
160))]
161use std::convert::TryInto;
162
163#[macro_use]
164mod macros;
165mod codec;
166
167#[cfg(feature = "futures-io")]
168pub mod futures;
169#[cfg(feature = "tokio")]
170pub mod tokio;
171
172mod unshared;
173mod util;
174
175#[cfg(feature = "brotli")]
176pub mod brotli;
177#[cfg(feature = "lz4")]
178pub mod lz4;
179#[cfg(feature = "zstd")]
180pub mod zstd;
181
182#[non_exhaustive]
184#[derive(Clone, Copy, Debug)]
185pub enum Level {
186 Fastest,
188
189 Best,
191
192 Default,
194
195 Precise(i32),
199}
200
201impl Level {
202 #[cfg(feature = "brotli")]
203 fn into_brotli(
204 self,
205 mut params: ::brotli::enc::backward_references::BrotliEncoderParams,
206 ) -> ::brotli::enc::backward_references::BrotliEncoderParams {
207 match self {
208 Self::Fastest => params.quality = 0,
209 Self::Best => params.quality = 11,
210 Self::Precise(quality) => params.quality = quality.clamp(0, 11),
211 Self::Default => (),
212 }
213
214 params
215 }
216
217 #[cfg(feature = "bzip2")]
218 fn into_bzip2(self) -> bzip2::Compression {
219 let fastest = bzip2::Compression::fast();
220 let best = bzip2::Compression::best();
221
222 match self {
223 Self::Fastest => fastest,
224 Self::Best => best,
225 Self::Precise(quality) => bzip2::Compression::new(
226 quality
227 .try_into()
228 .unwrap_or(0)
229 .clamp(fastest.level(), best.level()),
230 ),
231 Self::Default => bzip2::Compression::default(),
232 }
233 }
234
235 #[cfg(feature = "flate2")]
236 fn into_flate2(self) -> flate2::Compression {
237 let fastest = flate2::Compression::fast();
238 let best = flate2::Compression::best();
239 let none = flate2::Compression::none();
240
241 match self {
242 Self::Fastest => fastest,
243 Self::Best => best,
244 Self::Precise(quality) => flate2::Compression::new(
245 quality
246 .try_into()
247 .unwrap_or(0)
248 .clamp(none.level(), best.level()),
249 ),
250 Self::Default => flate2::Compression::default(),
251 }
252 }
253
254 #[cfg(feature = "zstd")]
255 fn into_zstd(self) -> i32 {
256 let (fastest, best) = libzstd::compression_level_range().into_inner();
257
258 const OUR_FASTEST: i32 = 1;
263
264 match self {
265 Self::Fastest => OUR_FASTEST,
266 Self::Best => best,
267 Self::Precise(quality) => quality.clamp(fastest, best),
268 Self::Default => libzstd::DEFAULT_COMPRESSION_LEVEL,
269 }
270 }
271
272 #[cfg(feature = "lzma")]
273 fn into_xz2(self) -> u32 {
274 match self {
275 Self::Fastest => 0,
276 Self::Best => 9,
277 Self::Precise(quality) => quality.try_into().unwrap_or(0).min(9),
278 Self::Default => 5,
279 }
280 }
281
282 #[cfg(feature = "lz4")]
283 fn into_lz4(
284 self,
285 mut preferences: ::lz4::liblz4::LZ4FPreferences,
286 ) -> ::lz4::liblz4::LZ4FPreferences {
287 let level = match self {
288 Self::Fastest => 0,
289 Self::Best => 12,
290 Self::Precise(quality) => quality.try_into().unwrap_or(0).min(12),
291 Self::Default => 0,
292 };
293
294 preferences.compression_level = level;
295 preferences
296 }
297}