/rust/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.9/src/lib.rs
Line | Count | Source |
1 | | //! A DEFLATE-based stream compression/decompression library |
2 | | //! |
3 | | //! This library provides support for compression and decompression of |
4 | | //! DEFLATE-based streams: |
5 | | //! |
6 | | //! * the DEFLATE format itself |
7 | | //! * the zlib format |
8 | | //! * gzip |
9 | | //! |
10 | | //! These three formats are all closely related and largely only differ in their |
11 | | //! headers/footers. This crate has three types in each submodule for dealing |
12 | | //! with these three formats. |
13 | | //! |
14 | | //! # Implementation |
15 | | //! |
16 | | //! In addition to supporting three formats, this crate supports several different |
17 | | //! backends, controlled through this crate's *features flags*: |
18 | | //! |
19 | | //! * `default`, or `rust_backend` - this implementation currently uses the `miniz_oxide` |
20 | | //! crate which is a port of `miniz.c` to Rust. This feature does not |
21 | | //! require a C compiler, and only uses safe Rust code. |
22 | | //! |
23 | | //! Note that the `rust_backend` feature may at some point be switched to use `zlib-rs`, |
24 | | //! and that `miniz_oxide` should be used explicitly if this is not desired. |
25 | | //! |
26 | | //! * `zlib-rs` - this implementation utilizes the `zlib-rs` crate, a Rust rewrite of zlib. |
27 | | //! This backend is the fastest, at the cost of some `unsafe` Rust code. |
28 | | //! |
29 | | //! Several backends implemented in C are also available. |
30 | | //! These are useful in case you are already using a specific C implementation |
31 | | //! and need the result of compression to be bit-identical. |
32 | | //! See the crate's README for details on the available C backends. |
33 | | //! |
34 | | //! The `zlib-rs` backend typically outperforms all the C implementations. |
35 | | //! |
36 | | //! # Feature Flags |
37 | | #![cfg_attr( |
38 | | not(feature = "document-features"), |
39 | | doc = "Activate the `document-features` cargo feature to see feature docs here" |
40 | | )] |
41 | | #![cfg_attr(feature = "document-features", doc = document_features::document_features!())] |
42 | | //! |
43 | | //! ## Ambiguous feature selection |
44 | | //! |
45 | | //! As Cargo features are additive, while backends are not, there is an order in which backends |
46 | | //! become active if multiple are selected. |
47 | | //! |
48 | | //! * zlib-ng |
49 | | //! * zlib-rs |
50 | | //! * cloudflare_zlib |
51 | | //! * miniz_oxide |
52 | | //! |
53 | | //! # Organization |
54 | | //! |
55 | | //! This crate consists of three main modules: `bufread`, `read`, and `write`. Each module |
56 | | //! implements DEFLATE, zlib, and gzip for [`std::io::BufRead`] input types, [`std::io::Read`] input |
57 | | //! types, and [`std::io::Write`] output types respectively. |
58 | | //! |
59 | | //! Use the [`mod@bufread`] implementations if you can provide a `BufRead` type for the input. |
60 | | //! The `&[u8]` slice type implements the `BufRead` trait. |
61 | | //! |
62 | | //! The [`mod@read`] implementations conveniently wrap a `Read` type in a `BufRead` implementation. |
63 | | //! However, the `read` implementations may |
64 | | //! [read past the end of the input data](https://github.com/rust-lang/flate2-rs/issues/338), |
65 | | //! making the `Read` type useless for subsequent reads of the input. If you need to re-use the |
66 | | //! `Read` type, wrap it in a [`std::io::BufReader`], use the `bufread` implementations, |
67 | | //! and perform subsequent reads on the `BufReader`. |
68 | | //! |
69 | | //! The [`mod@write`] implementations are most useful when there is no way to create a `BufRead` |
70 | | //! type, notably when reading async iterators (streams). |
71 | | //! |
72 | | //! ``` |
73 | | //! use futures::{Stream, StreamExt}; |
74 | | //! use std::io::{Result, Write as _}; |
75 | | //! |
76 | | //! async fn decompress_gzip_stream<S, I>(stream: S) -> Result<Vec<u8>> |
77 | | //! where |
78 | | //! S: Stream<Item = I>, |
79 | | //! I: AsRef<[u8]> |
80 | | //! { |
81 | | //! let mut stream = std::pin::pin!(stream); |
82 | | //! let mut w = Vec::<u8>::new(); |
83 | | //! let mut decoder = flate2::write::GzDecoder::new(w); |
84 | | //! while let Some(input) = stream.next().await { |
85 | | //! decoder.write_all(input.as_ref())?; |
86 | | //! } |
87 | | //! decoder.finish() |
88 | | //! } |
89 | | //! ``` |
90 | | //! |
91 | | //! |
92 | | //! Note that types which operate over a specific trait often implement the mirroring trait as well. |
93 | | //! For example a `bufread::DeflateDecoder<T>` *also* implements the |
94 | | //! [`Write`] trait if `T: Write`. That is, the "dual trait" is forwarded directly |
95 | | //! to the underlying object if available. |
96 | | //! |
97 | | //! # About multi-member Gzip files |
98 | | //! |
99 | | //! While most `gzip` files one encounters will have a single *member* that can be read |
100 | | //! with the [`GzDecoder`], there may be some files which have multiple members. |
101 | | //! |
102 | | //! A [`GzDecoder`] will only read the first member of gzip data, which may unexpectedly |
103 | | //! provide partial results when a multi-member gzip file is encountered. `GzDecoder` is appropriate |
104 | | //! for data that is designed to be read as single members from a multi-member file. `bufread::GzDecoder` |
105 | | //! and `write::GzDecoder` also allow non-gzip data following gzip data to be handled. |
106 | | //! |
107 | | //! The [`MultiGzDecoder`] on the other hand will decode all members of a `gzip` file |
108 | | //! into one consecutive stream of bytes, which hides the underlying *members* entirely. |
109 | | //! If a file contains non-gzip data after the gzip data, MultiGzDecoder will |
110 | | //! emit an error after decoding the gzip data. This behavior matches the `gzip`, |
111 | | //! `gunzip`, and `zcat` command line tools. |
112 | | //! |
113 | | //! [`Bufread`]: std::io::BufRead |
114 | | //! [`BufReader`]: std::io::BufReader |
115 | | //! [`Read`]: std::io::Read |
116 | | //! [`Write`]: std::io::Write |
117 | | //! [`GzDecoder`]: bufread::GzDecoder |
118 | | //! [`MultiGzDecoder`]: bufread::MultiGzDecoder |
119 | | #![doc(html_root_url = "https://docs.rs/flate2/0.2")] |
120 | | #![deny(missing_docs)] |
121 | | #![deny(missing_debug_implementations)] |
122 | | #![allow(trivial_numeric_casts)] |
123 | | #![cfg_attr(test, deny(warnings))] |
124 | | #![cfg_attr(docsrs, feature(doc_cfg))] |
125 | | |
126 | | #[cfg(not(feature = "any_impl",))] |
127 | | compile_error!("You need to choose a zlib backend"); |
128 | | |
129 | | pub use crate::crc::{Crc, CrcReader, CrcWriter}; |
130 | | pub use crate::gz::GzBuilder; |
131 | | pub use crate::gz::GzHeader; |
132 | | pub use crate::mem::{Compress, CompressError, Decompress, DecompressError, Status}; |
133 | | pub use crate::mem::{FlushCompress, FlushDecompress}; |
134 | | |
135 | | mod bufreader; |
136 | | mod crc; |
137 | | mod deflate; |
138 | | mod ffi; |
139 | | mod gz; |
140 | | mod mem; |
141 | | mod zio; |
142 | | mod zlib; |
143 | | |
144 | | /// Types which operate over [`Read`] streams, both encoders and decoders for |
145 | | /// various formats. |
146 | | /// |
147 | | /// Note that the `read` decoder types may read past the end of the compressed |
148 | | /// data while decoding. If the caller requires subsequent reads to start |
149 | | /// immediately following the compressed data wrap the `Read` type in a |
150 | | /// [`BufReader`] and use the `BufReader` with the equivalent decoder from the |
151 | | /// `bufread` module and also for the subsequent reads. |
152 | | /// |
153 | | /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html |
154 | | /// [`BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html |
155 | | pub mod read { |
156 | | pub use crate::deflate::read::DeflateDecoder; |
157 | | pub use crate::deflate::read::DeflateEncoder; |
158 | | pub use crate::gz::read::GzDecoder; |
159 | | pub use crate::gz::read::GzEncoder; |
160 | | pub use crate::gz::read::MultiGzDecoder; |
161 | | pub use crate::zlib::read::ZlibDecoder; |
162 | | pub use crate::zlib::read::ZlibEncoder; |
163 | | } |
164 | | |
165 | | /// Types which operate over [`Write`] streams, both encoders and decoders for |
166 | | /// various formats. |
167 | | /// |
168 | | /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html |
169 | | pub mod write { |
170 | | pub use crate::deflate::write::DeflateDecoder; |
171 | | pub use crate::deflate::write::DeflateEncoder; |
172 | | pub use crate::gz::write::GzDecoder; |
173 | | pub use crate::gz::write::GzEncoder; |
174 | | pub use crate::gz::write::MultiGzDecoder; |
175 | | pub use crate::zlib::write::ZlibDecoder; |
176 | | pub use crate::zlib::write::ZlibEncoder; |
177 | | } |
178 | | |
179 | | /// Types which operate over [`BufRead`] streams, both encoders and decoders for |
180 | | /// various formats. |
181 | | /// |
182 | | /// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html |
183 | | pub mod bufread { |
184 | | pub use crate::deflate::bufread::DeflateDecoder; |
185 | | pub use crate::deflate::bufread::DeflateEncoder; |
186 | | pub use crate::gz::bufread::GzDecoder; |
187 | | pub use crate::gz::bufread::GzEncoder; |
188 | | pub use crate::gz::bufread::MultiGzDecoder; |
189 | | pub use crate::zlib::bufread::ZlibDecoder; |
190 | | pub use crate::zlib::bufread::ZlibEncoder; |
191 | | } |
192 | | |
193 | 0 | fn _assert_send_sync() { |
194 | 0 | fn _assert_send_sync<T: Send + Sync>() {} |
195 | | |
196 | 0 | _assert_send_sync::<read::DeflateEncoder<&[u8]>>(); |
197 | 0 | _assert_send_sync::<read::DeflateDecoder<&[u8]>>(); |
198 | 0 | _assert_send_sync::<read::ZlibEncoder<&[u8]>>(); |
199 | 0 | _assert_send_sync::<read::ZlibDecoder<&[u8]>>(); |
200 | 0 | _assert_send_sync::<read::GzEncoder<&[u8]>>(); |
201 | 0 | _assert_send_sync::<read::GzDecoder<&[u8]>>(); |
202 | 0 | _assert_send_sync::<read::MultiGzDecoder<&[u8]>>(); |
203 | 0 | _assert_send_sync::<write::DeflateEncoder<Vec<u8>>>(); |
204 | 0 | _assert_send_sync::<write::DeflateDecoder<Vec<u8>>>(); |
205 | 0 | _assert_send_sync::<write::ZlibEncoder<Vec<u8>>>(); |
206 | 0 | _assert_send_sync::<write::ZlibDecoder<Vec<u8>>>(); |
207 | 0 | _assert_send_sync::<write::GzEncoder<Vec<u8>>>(); |
208 | 0 | _assert_send_sync::<write::GzDecoder<Vec<u8>>>(); |
209 | 0 | } |
210 | | |
211 | | /// When compressing data, the compression level can be specified by a value in |
212 | | /// this struct. |
213 | | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
214 | | pub struct Compression(u32); |
215 | | |
216 | | impl Compression { |
217 | | /// Creates a new description of the compression level with an explicitly |
218 | | /// specified integer. |
219 | | /// |
220 | | /// The integer here is typically on a scale of 0-9 where 0 means "no |
221 | | /// compression" and 9 means "take as long as you'd like". |
222 | 0 | pub const fn new(level: u32) -> Compression { |
223 | 0 | Compression(level) |
224 | 0 | } |
225 | | |
226 | | /// No compression is to be performed, this may actually inflate data |
227 | | /// slightly when encoding. |
228 | 0 | pub const fn none() -> Compression { |
229 | 0 | Compression(0) |
230 | 0 | } |
231 | | |
232 | | /// Optimize for the best speed of encoding. |
233 | 0 | pub const fn fast() -> Compression { |
234 | 0 | Compression(1) |
235 | 0 | } |
236 | | |
237 | | /// Optimize for the size of data being encoded. |
238 | 0 | pub const fn best() -> Compression { |
239 | 0 | Compression(9) |
240 | 0 | } |
241 | | |
242 | | /// Returns an integer representing the compression level, typically on a |
243 | | /// scale of 0-9. See [`new`](Self::new) for details about compression levels. |
244 | 0 | pub fn level(&self) -> u32 { |
245 | 0 | self.0 |
246 | 0 | } |
247 | | } |
248 | | |
249 | | impl Default for Compression { |
250 | 0 | fn default() -> Compression { |
251 | 0 | Compression(6) |
252 | 0 | } |
253 | | } |
254 | | |
255 | | #[cfg(test)] |
256 | | fn random_bytes() -> impl Iterator<Item = u8> { |
257 | | use rand::Rng; |
258 | | use std::iter; |
259 | | |
260 | | iter::repeat(()).map(|_| rand::rng().random()) |
261 | | } |