async_compression/
macros.rs

1macro_rules! algos {
2    (@algo $algo:ident [$algo_s:expr] $decoder:ident $encoder:ident <$inner:ident>
3        { @enc $($encoder_methods:tt)* }
4        { @dec $($decoder_methods:tt)* }
5    ) => {
6        #[cfg(feature = $algo_s)]
7        decoder! {
8            #[doc = concat!("A ", $algo_s, " decoder, or decompressor")]
9            #[cfg(feature = $algo_s)]
10            $decoder<$inner>
11
12            { $($decoder_methods)* }
13        }
14
15        #[cfg(feature = $algo_s)]
16        encoder! {
17            #[doc = concat!("A ", $algo_s, " encoder, or compressor.")]
18            #[cfg(feature = $algo_s)]
19            $encoder<$inner> {
20                pub fn new(inner: $inner) -> Self {
21                    Self::with_quality(inner, crate::core::Level::Default)
22                }
23            }
24
25            { $($encoder_methods)* }
26        }
27    };
28
29    (@algo $algo:ident [$algo_s:expr] $decoder:ident $encoder:ident <$inner:ident>
30        { @dec $($decoder_methods:tt)* }
31    ) => {
32        #[cfg(feature = $algo_s)]
33        decoder! {
34            #[doc = concat!("A ", $algo_s, " decoder, or decompressor")]
35            #[cfg(feature = $algo_s)]
36            $decoder<$inner>
37
38            { $($decoder_methods)* }
39        }
40    };
41
42    ($($mod:ident)::+ <$inner:ident>) => {
43        algos!(@algo brotli ["brotli"] BrotliDecoder BrotliEncoder <$inner>
44        { @enc
45            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
46                // let params = brotli::enc::backward_references::BrotliEncoderParams::default();
47                let params = crate::codecs::brotli::params::EncoderParams::default();
48                let params = params.quality(level);
49                Self {
50                    inner: crate::$($mod::)+generic::Encoder::new(
51                        inner,
52                        crate::codecs::BrotliEncoder::new(params),
53                    ),
54                }
55            }
56
57            /// Creates a new encoder, using the specified compression level and parameters, which
58            /// will read uncompressed data from the given stream and emit a compressed stream.
59            pub fn with_params(
60                inner: $inner,
61                params: crate::codecs::brotli::params::EncoderParams,
62            ) -> Self {
63                Self {
64                    inner: crate::$($mod::)+generic::Encoder::new(
65                        inner,
66                        crate::codecs::BrotliEncoder::new(params),
67                    ),
68                }
69            }
70        }
71        { @dec }
72        );
73
74        algos!(@algo bzip2 ["bzip2"] BzDecoder BzEncoder <$inner>
75        { @enc
76
77            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
78                let params = crate::codecs::bzip2::params::Bzip2EncoderParams::from(level);
79                Self {
80                    inner: crate::$($mod::)+generic::Encoder::new(
81                        inner,
82                        crate::codecs::BzEncoder::new(params, 0),
83                    ),
84                }
85            }
86        }
87        { @dec }
88        );
89
90        algos!(@algo deflate ["deflate"] DeflateDecoder DeflateEncoder <$inner>
91        { @enc
92            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
93                let mut params = crate::codecs::flate::params::FlateEncoderParams::from(level);
94
95                Self {
96                    inner: crate::$($mod::)+generic::Encoder::new(
97                        inner,
98                        crate::codecs::DeflateEncoder::new(params),
99                    ),
100                }
101            }
102
103            /// Returns the total number of input bytes which have been processed by this compression object.
104            pub fn total_in(&self) -> u64 {
105                self.inner.get_encoder_ref().get_ref().get_ref().total_in()
106            }
107
108            /// Returns the total number of output bytes which have been produced by this compression object.
109            pub fn total_out(&self) -> u64 {
110                self.inner.get_encoder_ref().get_ref().get_ref().total_out()
111            }
112        }
113        { @dec }
114        );
115
116        algos!(@algo deflate ["deflate64"] Deflate64Decoder Deflate64Encoder <$inner>
117        { @dec }
118        );
119
120        algos!(@algo gzip ["gzip"] GzipDecoder GzipEncoder <$inner>
121        { @enc
122
123            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
124                let params = crate::codecs::flate::params::FlateEncoderParams::from(level);
125                Self {
126                    inner: crate::$($mod::)+generic::Encoder::new(
127                        inner,
128                        crate::codecs::GzipEncoder::new(params),
129                    ),
130                }
131            }
132        }
133        { @dec }
134        );
135
136        algos!(@algo zlib ["zlib"] ZlibDecoder ZlibEncoder <$inner>
137        { @enc
138            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
139                  let params = crate::codecs::flate::params::FlateEncoderParams::from(level);
140                Self {
141                    inner: crate::$($mod::)+generic::Encoder::new(
142                        inner,
143                        crate::codecs::ZlibEncoder::new(params),
144                    ),
145                }
146            }
147
148            /// Returns the total number of input bytes which have been processed by this compression object.
149            pub fn total_in(&self) -> u64 {
150                self.inner.get_encoder_ref().get_ref().get_ref().total_in()
151            }
152
153            /// Returns the total number of output bytes which have been produced by this compression object.
154            pub fn total_out(&self) -> u64 {
155                self.inner.get_encoder_ref().get_ref().get_ref().total_out()
156            }
157        }
158        { @dec }
159        );
160
161        algos!(@algo zstd ["zstd"] ZstdDecoder ZstdEncoder <$inner>
162        { @enc
163
164            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
165                let params = crate::codecs::zstd::params::CParameter::quality(level);
166                Self {
167                    inner: crate::$($mod::)+generic::Encoder::new(
168                        inner,
169                        crate::codecs::ZstdEncoder::new(params),
170                    ),
171                }
172            }
173
174            /// Creates a new encoder, using the specified compression level and parameters, which
175            /// will read uncompressed data from the given stream and emit a compressed stream.
176            ///
177            /// # Panics
178            ///
179            /// Panics if this function is called with a [`CParameter::nb_workers()`] parameter and
180            /// the `zstdmt` crate feature is _not_ enabled.
181            ///
182            /// [`CParameter::nb_workers()`]: crate::codecs::zstd::params::CParameter
183            //
184            // TODO: remove panic note on next breaking release, along with `CParameter::nb_workers`
185            // change
186            pub fn with_quality_and_params(inner: $inner, level: crate::core::Level, params: &[crate::codecs::zstd::params::CParameter]) -> Self {
187                let level = crate::codecs::zstd::params::CParameter::quality(level);
188                Self {
189                    inner: crate::$($mod::)+generic::Encoder::new(
190                        inner,
191                        crate::codecs::ZstdEncoder::new_with_params(level, params),
192                    ),
193                }
194            }
195
196            /// Creates a new encoder, using the specified compression level and pre-trained
197            /// dictionary, which will read uncompressed data from the given stream and emit a
198            /// compressed stream.
199            ///
200            /// Dictionaries provide better compression ratios for small files, but are required to
201            /// be present during decompression.
202            ///
203            /// # Errors
204            ///
205            /// Returns error when `dictionary` is not valid.
206            pub fn with_dict(inner: $inner, level: crate::core::Level, dictionary: &[u8]) -> ::std::io::Result<Self> {
207                let level = crate::codecs::zstd::params::CParameter::quality(level);
208                Ok(Self {
209                    inner: crate::$($mod::)+generic::Encoder::new(
210                        inner,
211                        crate::codecs::ZstdEncoder::new_with_dict(level, dictionary)?,
212                    ),
213                })
214            }
215        }
216        { @dec
217            /// Creates a new decoder, using the specified parameters, which will read compressed
218            /// data from the given stream and emit a decompressed stream.
219            pub fn with_params(inner: $inner, params: &[crate::codecs::zstd::params::DParameter]) -> Self {
220                Self {
221                    inner: crate::$($mod::)+generic::Decoder::new(
222                        inner,
223                        crate::codecs::ZstdDecoder::new_with_params(params),
224                    ),
225                }
226            }
227
228            /// Creates a new decoder, using the specified compression level and pre-trained
229            /// dictionary, which will read compressed data from the given stream and emit an
230            /// uncompressed stream.
231            ///
232            /// Dictionaries provide better compression ratios for small files, but are required to
233            /// be present during decompression. The dictionary used must be the same as the one
234            /// used for compression.
235            ///
236            /// # Errors
237            ///
238            /// Returns error when `dictionary` is not valid.
239            pub fn with_dict(inner: $inner, dictionary: &[u8]) -> ::std::io::Result<Self> {
240                Ok(Self {
241                    inner: crate::$($mod::)+generic::Decoder::new(
242                        inner,
243                        crate::codecs::ZstdDecoder::new_with_dict(dictionary)?,
244                    ),
245                })
246            }
247        }
248        );
249
250        algos!(@algo xz ["xz"] XzDecoder XzEncoder <$inner>
251        { @enc
252
253            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
254                Self {
255                    inner: crate::$($mod::)+generic::Encoder::new(
256                        inner,
257                        crate::codecs::XzEncoder::new(level),
258                    ),
259                }
260            }
261
262            /// Creates a new multi-threaded encoder.
263            ///
264            /// Note that flushing will severely impact multi-threaded performance.
265            #[cfg(feature = "xz-parallel")]
266            pub fn parallel(inner: $inner, level: crate::core::Level, threads: std::num::NonZeroU32) -> Self {
267                Self {
268                    inner: crate::$($mod::)+generic::Encoder::new(
269                        inner,
270                        crate::codecs::XzEncoder::parallel(threads, level),
271                    ),
272                }
273            }
274        }
275        { @dec
276            /// Creates a new decoder with the specified limit of memory.
277            ///
278            /// # Errors
279            ///
280            /// An IO error may be returned during decoding if the specified limit is too small.
281            pub fn with_mem_limit(read: $inner, memlimit: u64) -> Self {
282                Self {
283                    inner: crate::$($mod::)+generic::Decoder::new(
284                        read,
285                        crate::codecs::XzDecoder::with_memlimit(memlimit),
286                    ),
287                }
288            }
289
290            /// Creates a new multi-threaded decoder.
291            #[cfg(feature = "xz-parallel")]
292            pub fn parallel(read: $inner, threads: std::num::NonZeroU32) -> Self {
293                use std::convert::TryInto;
294
295                Self {
296                    inner: crate::$($mod::)+generic::Decoder::new(
297                        read,
298                        crate::codecs::XzDecoder::parallel(threads, usize::MAX.try_into().unwrap()),
299                    ),
300                }
301            }
302
303            /// Creates a new multi-threaded decoder with the specified limit of memory.
304            ///
305            /// # Errors
306            ///
307            /// An IO error may be returned during decoding if the specified limit is too small.
308            #[cfg(feature = "xz-parallel")]
309            pub fn parallel_with_mem_limit(read: $inner, threads: std::num::NonZeroU32, memlimit: u64) -> Self {
310                Self {
311                    inner: crate::$($mod::)+generic::Decoder::new(
312                        read,
313                        crate::codecs::XzDecoder::parallel(threads, memlimit),
314                    ),
315                }
316            }
317        }
318        );
319
320        algos!(@algo lzma ["lzma"] LzmaDecoder LzmaEncoder <$inner>
321        { @enc
322
323            pub fn with_quality(inner: $inner, level:  crate::core::Level) -> Self {
324                let encoder = crate::codecs::LzmaEncoder::new(level);
325                let inner =  crate::$($mod::)+generic::Encoder::new(inner, encoder);
326                Self {
327                    inner
328                }
329            }
330        }
331        { @dec
332            /// Creates a new decoder with the specified limit of memory.
333            ///
334            /// # Errors
335            ///
336            /// An IO error may be returned during decoding if the specified limit is too small.
337            pub fn with_mem_limit(read: $inner, memlimit: u64) -> Self {
338                Self {
339                    inner: crate::$($mod::)+generic::Decoder::new(
340                        read,
341                        crate::codecs::LzmaDecoder::with_memlimit(memlimit),
342                    ),
343                }
344            }
345
346        }
347        );
348
349        algos!(@algo lz4 ["lz4"] Lz4Decoder Lz4Encoder <$inner>
350        { @enc
351
352            pub fn with_quality(inner: $inner, level: crate::core::Level) -> Self {
353                Self::with_quality_and_params(inner, level, crate::codecs::lz4::params::EncoderParams::default())
354            }
355
356            /// Creates a new encoder, using the specified compression level and parameters, which
357            /// will read uncompressed data from the given stream and emit a compressed stream.
358            pub fn with_quality_and_params(
359                inner: $inner,
360                level: crate::core::Level,
361                mut params: crate::codecs::lz4::params::EncoderParams,
362            ) -> Self {
363                let params = params.level(level);
364                let encoder = crate::codecs::Lz4Encoder::new(params);
365                let cap = encoder.buffer_size();
366                Self {
367                    inner: crate::$($mod::)+generic::Encoder::with_capacity(
368                        inner,
369                        encoder,
370                        cap,
371                    ),
372                }
373            }
374        }
375        { @dec }
376        );
377
378    }
379}