1#![allow(unexpected_cfgs)]
33# | [`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# | [`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))]
142#![warn(
143 missing_docs,
144 rust_2018_idioms,
145 missing_copy_implementations,
146 missing_debug_implementations
147)]
148#![cfg_attr(not(all), allow(unused))]
149
150#[cfg(any(
151 feature = "bzip2",
152 feature = "flate2",
153 feature = "lzma",
154 feature = "lz4"
155))]
156use std::convert::TryInto;
157
158#[macro_use]
159mod macros;
160mod codec;
161
162#[cfg(feature = "futures-io")]
163pub mod futures;
164#[cfg(feature = "tokio")]
165pub mod tokio;
166
167mod unshared;
168mod util;
169
170#[cfg(feature = "brotli")]
171pub mod brotli;
172#[cfg(feature = "lz4")]
173pub mod lz4;
174#[cfg(feature = "zstd")]
175pub mod zstd;
176
177#[non_exhaustive]
179#[derive(Clone, Copy, Debug)]
180pub enum Level {
181 Fastest,
183
184 Best,
186
187 Default,
189
190 Precise(i32),
194}
195
196impl Level {
197 #[cfg(feature = "brotli")]
198 fn into_brotli(
199 self,
200 mut params: ::brotli::enc::backward_references::BrotliEncoderParams,
201 ) -> ::brotli::enc::backward_references::BrotliEncoderParams {
202 match self {
203 Self::Fastest => params.quality = 0,
204 Self::Best => params.quality = 11,
205 Self::Precise(quality) => params.quality = quality.clamp(0, 11),
206 Self::Default => (),
207 }
208
209 params
210 }
211
212 #[cfg(feature = "bzip2")]
213 fn into_bzip2(self) -> bzip2::Compression {
214 let fastest = bzip2::Compression::fast();
215 let best = bzip2::Compression::best();
216
217 match self {
218 Self::Fastest => fastest,
219 Self::Best => best,
220 Self::Precise(quality) => bzip2::Compression::new(
221 quality
222 .try_into()
223 .unwrap_or(0)
224 .clamp(fastest.level(), best.level()),
225 ),
226 Self::Default => bzip2::Compression::default(),
227 }
228 }
229
230 #[cfg(feature = "flate2")]
231 fn into_flate2(self) -> flate2::Compression {
232 let fastest = flate2::Compression::fast();
233 let best = flate2::Compression::best();
234 let none = flate2::Compression::none();
235
236 match self {
237 Self::Fastest => fastest,
238 Self::Best => best,
239 Self::Precise(quality) => flate2::Compression::new(
240 quality
241 .try_into()
242 .unwrap_or(0)
243 .clamp(none.level(), best.level()),
244 ),
245 Self::Default => flate2::Compression::default(),
246 }
247 }
248
249 #[cfg(feature = "zstd")]
250 fn into_zstd(self) -> i32 {
251 let (fastest, best) = libzstd::compression_level_range().into_inner();
252 match self {
253 Self::Fastest => fastest,
254 Self::Best => best,
255 Self::Precise(quality) => quality.clamp(fastest, best),
256 Self::Default => libzstd::DEFAULT_COMPRESSION_LEVEL,
257 }
258 }
259
260 #[cfg(feature = "lzma")]
261 fn into_xz2(self) -> u32 {
262 match self {
263 Self::Fastest => 0,
264 Self::Best => 9,
265 Self::Precise(quality) => quality.try_into().unwrap_or(0).min(9),
266 Self::Default => 5,
267 }
268 }
269
270 #[cfg(feature = "lz4")]
271 fn into_lz4(
272 self,
273 mut preferences: ::lz4::liblz4::LZ4FPreferences,
274 ) -> ::lz4::liblz4::LZ4FPreferences {
275 let level = match self {
276 Self::Fastest => 0,
277 Self::Best => 12,
278 Self::Precise(quality) => quality.try_into().unwrap_or(0).min(12),
279 Self::Default => 0,
280 };
281
282 preferences.compression_level = level;
283 preferences
284 }
285}