flate2_expose/lib.rs
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:
18//!
19//! * `default`, or `rust_backend` - this implementation uses the `miniz_oxide`
20//! crate which is a port of `miniz.c` (below) to Rust. This feature does not
21//! require a C compiler and only requires Rust code.
22//!
23//! * `zlib` - this feature will enable linking against the `libz` library, typically found on most
24//! Linux systems by default. If the library isn't found to already be on the system it will be
25//! compiled from source (this is a C library).
26//!
27//! There's various tradeoffs associated with each implementation, but in general you probably
28//! won't have to tweak the defaults. The default choice is selected to avoid the need for a C
29//! compiler at build time. `zlib-ng-compat` is useful if you're using zlib for compatibility but
30//! want performance via zlib-ng's zlib-compat mode. `zlib` is useful if something else in your
31//! dependencies links the original zlib so you cannot use zlib-ng-compat. The compression ratios
32//! and performance of each of these feature should be roughly comparable, but you'll likely want
33//! to run your own tests if you're curious about the performance.
34//!
35//! # Organization
36//!
37//! This crate consists mainly of three modules, [`read`], [`write`], and
38//! [`bufread`]. Each module contains a number of types used to encode and
39//! decode various streams of data.
40//!
41//! All types in the [`write`] module work on instances of [`Write`][write],
42//! whereas all types in the [`read`] module work on instances of
43//! [`Read`][read] and [`bufread`] works with [`BufRead`][bufread]. If you
44//! are decoding directly from a `&[u8]`, use the [`bufread`] types.
45//!
46//! ```
47//! use flate2_expose::write::GzEncoder;
48//! use flate2_expose::Compression;
49//! use std::io;
50//! use std::io::prelude::*;
51//!
52//! # fn main() { let _ = run(); }
53//! # fn run() -> io::Result<()> {
54//! let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
55//! encoder.write_all(b"Example")?;
56//! # Ok(())
57//! # }
58//! ```
59//!
60//!
61//! Other various types are provided at the top-level of the crate for
62//! management and dealing with encoders/decoders. Also note that types which
63//! operate over a specific trait often implement the mirroring trait as well.
64//! For example a `flate2_expose::read::DeflateDecoder<T>` *also* implements the
65//! `Write` trait if `T: Write`. That is, the "dual trait" is forwarded directly
66//! to the underlying object if available.
67//!
68//! [`read`]: read/index.html
69//! [`bufread`]: bufread/index.html
70//! [`write`]: write/index.html
71//! [read]: https://doc.rust-lang.org/std/io/trait.Read.html
72//! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
73//! [bufread]: https://doc.rust-lang.org/std/io/trait.BufRead.html
74#![doc(html_root_url = "https://docs.rs/flate2_expose/0.2")]
75#![deny(missing_docs)]
76#![deny(missing_debug_implementations)]
77#![allow(trivial_numeric_casts)]
78#![cfg_attr(test, deny(warnings))]
79
80pub use crate::crc::{Crc, CrcReader, CrcWriter};
81pub use crate::gz::GzBuilder;
82pub use crate::gz::GzHeader;
83pub use crate::mem::{Compress, CompressError, Decompress, DecompressError, Status};
84pub use crate::mem::{FlushCompress, FlushDecompress};
85
86mod bufreader;
87mod crc;
88mod deflate;
89mod ffi;
90mod gz;
91mod mem;
92mod zio;
93mod zlib;
94
95/// Types which operate over [`Read`] streams, both encoders and decoders for
96/// various formats.
97///
98/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
99pub mod read {
100 pub use crate::deflate::read::DeflateDecoder;
101 pub use crate::deflate::read::DeflateEncoder;
102 pub use crate::gz::read::GzDecoder;
103 pub use crate::gz::read::GzEncoder;
104 pub use crate::gz::read::MultiGzDecoder;
105 pub use crate::zlib::read::ZlibDecoder;
106 pub use crate::zlib::read::ZlibEncoder;
107}
108
109/// Types which operate over [`Write`] streams, both encoders and decoders for
110/// various formats.
111///
112/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
113pub mod write {
114 pub use crate::deflate::write::DeflateDecoder;
115 pub use crate::deflate::write::DeflateEncoder;
116 pub use crate::gz::write::GzDecoder;
117 pub use crate::gz::write::GzEncoder;
118 pub use crate::zlib::write::ZlibDecoder;
119 pub use crate::zlib::write::ZlibEncoder;
120}
121
122/// Types which operate over [`BufRead`] streams, both encoders and decoders for
123/// various formats.
124///
125/// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html
126pub mod bufread {
127 pub use crate::deflate::bufread::DeflateDecoder;
128 pub use crate::deflate::bufread::DeflateEncoder;
129 pub use crate::gz::bufread::GzDecoder;
130 pub use crate::gz::bufread::GzEncoder;
131 pub use crate::gz::bufread::MultiGzDecoder;
132 pub use crate::zlib::bufread::ZlibDecoder;
133 pub use crate::zlib::bufread::ZlibEncoder;
134}
135
136fn _assert_send_sync() {
137 fn _assert_send_sync<T: Send + Sync>() {}
138
139 _assert_send_sync::<read::DeflateEncoder<&[u8]>>();
140 _assert_send_sync::<read::DeflateDecoder<&[u8]>>();
141 _assert_send_sync::<read::ZlibEncoder<&[u8]>>();
142 _assert_send_sync::<read::ZlibDecoder<&[u8]>>();
143 _assert_send_sync::<read::GzEncoder<&[u8]>>();
144 _assert_send_sync::<read::GzDecoder<&[u8]>>();
145 _assert_send_sync::<read::MultiGzDecoder<&[u8]>>();
146 _assert_send_sync::<write::DeflateEncoder<Vec<u8>>>();
147 _assert_send_sync::<write::DeflateDecoder<Vec<u8>>>();
148 _assert_send_sync::<write::ZlibEncoder<Vec<u8>>>();
149 _assert_send_sync::<write::ZlibDecoder<Vec<u8>>>();
150 _assert_send_sync::<write::GzEncoder<Vec<u8>>>();
151 _assert_send_sync::<write::GzDecoder<Vec<u8>>>();
152}
153
154/// When compressing data, the compression level can be specified by a value in
155/// this enum.
156#[derive(Copy, Clone, PartialEq, Eq, Debug)]
157pub struct Compression(u32);
158
159impl Compression {
160 /// Creates a new description of the compression level with an explicitly
161 /// specified integer.
162 ///
163 /// The integer here is typically on a scale of 0-9 where 0 means "no
164 /// compression" and 9 means "take as long as you'd like".
165 pub const fn new(level: u32) -> Compression {
166 Compression(level)
167 }
168
169 /// No compression is to be performed, this may actually inflate data
170 /// slightly when encoding.
171 pub const fn none() -> Compression {
172 Compression(0)
173 }
174
175 /// Optimize for the best speed of encoding.
176 pub const fn fast() -> Compression {
177 Compression(1)
178 }
179
180 /// Optimize for the size of data being encoded.
181 pub const fn best() -> Compression {
182 Compression(9)
183 }
184
185 /// Returns an integer representing the compression level, typically on a
186 /// scale of 0-9
187 pub fn level(&self) -> u32 {
188 self.0
189 }
190}
191
192impl Default for Compression {
193 fn default() -> Compression {
194 Compression(6)
195 }
196}
197
198#[cfg(test)]
199fn random_bytes() -> impl Iterator<Item = u8> {
200 use rand::Rng;
201 use std::iter;
202
203 iter::repeat(()).map(|_| rand::thread_rng().gen())
204}