gix_zlib/lib.rs
1#![deny(missing_docs)]
2//! Streaming compression and decompression utilities used by gitoxide.
3
4/// The compression level to use for zlib-based streams, in the range from 0 (no compression)
5/// to 9 (best compression, slowest).
6///
7/// Note that `git` maps its configured level of `-1` to the zlib default, which is level 6
8/// and available as [`Compression::DEFAULT`].
9#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Compression(i32);
12
13impl Compression {
14 /// Do not compress at all, while still producing a valid zlib stream.
15 pub const NONE: Compression = Compression(0);
16 /// The fastest compression, with the lowest compression ratio, also known as level 1.
17 ///
18 /// This is what `git` uses for loose objects unless configured otherwise with `core.looseCompression`.
19 pub const BEST_SPEED: Compression = Compression(1);
20 /// The default compromise between speed and compression ratio, also known as level 6.
21 ///
22 /// This is what `git` uses when writing packs unless configured otherwise with `pack.compression`.
23 pub const DEFAULT: Compression = Compression(6);
24 /// The best compression ratio at the expense of speed, also known as level 9.
25 pub const BEST: Compression = Compression(9);
26
27 /// Create a new instance from `level` if it is within the valid range from 0 to 9, inclusive.
28 pub fn new(level: i32) -> Option<Self> {
29 (0..=9).contains(&level).then_some(Compression(level))
30 }
31
32 /// Return the compression level as integer in the range from 0 to 9, inclusive.
33 pub fn level(&self) -> i32 {
34 self.0
35 }
36}
37
38impl Default for Compression {
39 fn default() -> Self {
40 Compression::DEFAULT
41 }
42}
43
44/// A type to hold all state needed for decompressing a ZLIB encoded stream.
45pub struct Decompress(zlib_rs::Inflate);
46
47/// The status returned by [`Decompress::decompress()`].
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum Status {
50 /// The decompress operation went well. Not to be confused with `StreamEnd`, so one can continue
51 /// the decompression.
52 Ok,
53 /// An error occurred when decompression.
54 BufError,
55 /// The stream was fully decompressed.
56 StreamEnd,
57}
58
59/// Values which indicate the form of flushing to be used when
60/// decompressing in-memory data.
61#[derive(Copy, Clone, PartialEq, Eq, Debug)]
62#[non_exhaustive]
63pub enum FlushDecompress {
64 /// A typical parameter for passing to compression/decompression functions,
65 /// this indicates that the underlying stream to decide how much data to
66 /// accumulate before producing output in order to maximize compression.
67 None = 0,
68
69 /// All pending output is flushed to the output buffer and the output is
70 /// aligned on a byte boundary so that the decompressor can get all input
71 /// data available so far.
72 ///
73 /// Flushing may degrade compression for some compression algorithms and so
74 /// it should only be used when necessary. This will complete the current
75 /// deflate block and follow it with an empty stored block.
76 Sync = 2,
77
78 /// Pending input is processed and pending output is flushed.
79 ///
80 /// The return value may indicate that the stream is not yet done and more
81 /// data has yet to be processed.
82 Finish = 4,
83}
84
85/// Decompress a few bytes of a zlib stream without allocation
86#[derive(Default)]
87pub struct Inflate {
88 /// The actual decompressor doing all the work.
89 pub state: Decompress,
90}
91
92/// Streaming compression and decompression utilities built on [`std::io`] traits.
93pub mod stream;
94
95/// Types supporting single-step, allocation-free decompression.
96pub mod inflate;
97
98mod decompress;
99pub use decompress::DecompressError;