binstall_zip/
compression.rs

1//! Possible ZIP compression methods.
2
3use std::fmt;
4
5#[allow(deprecated)]
6/// Identifies the storage format used to compress a file within a ZIP archive.
7///
8/// Each file's compression method is stored alongside it, allowing the
9/// contents to be read without context.
10///
11/// When creating ZIP files, you may choose the method to use with
12/// [`crate::write::FileOptions::compression_method`]
13#[derive(Copy, Clone, PartialEq, Eq, Debug)]
14#[non_exhaustive]
15pub enum CompressionMethod {
16    /// Store the file as is
17    Stored,
18    /// Compress the file using Deflate
19    #[cfg(any(
20        feature = "deflate",
21        feature = "deflate-miniz",
22        feature = "deflate-zlib"
23    ))]
24    Deflated,
25    /// Compress the file using BZIP2
26    #[cfg(feature = "bzip2")]
27    Bzip2,
28    /// Encrypted using AES.
29    ///
30    /// The actual compression method has to be taken from the AES extra data field
31    /// or from `ZipFileData`.
32    #[cfg(feature = "aes-crypto")]
33    Aes,
34    /// Compress the file using ZStandard
35    #[cfg(feature = "zstd")]
36    Zstd,
37    /// Unsupported compression method
38    #[deprecated(since = "0.5.7", note = "use the constants instead")]
39    Unsupported(u16),
40}
41#[allow(deprecated, missing_docs)]
42/// All compression methods defined for the ZIP format
43impl CompressionMethod {
44    pub const STORE: Self = CompressionMethod::Stored;
45    pub const SHRINK: Self = CompressionMethod::Unsupported(1);
46    pub const REDUCE_1: Self = CompressionMethod::Unsupported(2);
47    pub const REDUCE_2: Self = CompressionMethod::Unsupported(3);
48    pub const REDUCE_3: Self = CompressionMethod::Unsupported(4);
49    pub const REDUCE_4: Self = CompressionMethod::Unsupported(5);
50    pub const IMPLODE: Self = CompressionMethod::Unsupported(6);
51    #[cfg(any(
52        feature = "deflate",
53        feature = "deflate-miniz",
54        feature = "deflate-zlib"
55    ))]
56    pub const DEFLATE: Self = CompressionMethod::Deflated;
57    #[cfg(not(any(
58        feature = "deflate",
59        feature = "deflate-miniz",
60        feature = "deflate-zlib"
61    )))]
62    pub const DEFLATE: Self = CompressionMethod::Unsupported(8);
63    pub const DEFLATE64: Self = CompressionMethod::Unsupported(9);
64    pub const PKWARE_IMPLODE: Self = CompressionMethod::Unsupported(10);
65    #[cfg(feature = "bzip2")]
66    pub const BZIP2: Self = CompressionMethod::Bzip2;
67    #[cfg(not(feature = "bzip2"))]
68    pub const BZIP2: Self = CompressionMethod::Unsupported(12);
69    pub const LZMA: Self = CompressionMethod::Unsupported(14);
70    pub const IBM_ZOS_CMPSC: Self = CompressionMethod::Unsupported(16);
71    pub const IBM_TERSE: Self = CompressionMethod::Unsupported(18);
72    pub const ZSTD_DEPRECATED: Self = CompressionMethod::Unsupported(20);
73    #[cfg(feature = "zstd")]
74    pub const ZSTD: Self = CompressionMethod::Zstd;
75    #[cfg(not(feature = "zstd"))]
76    pub const ZSTD: Self = CompressionMethod::Unsupported(93);
77    pub const MP3: Self = CompressionMethod::Unsupported(94);
78    pub const XZ: Self = CompressionMethod::Unsupported(95);
79    pub const JPEG: Self = CompressionMethod::Unsupported(96);
80    pub const WAVPACK: Self = CompressionMethod::Unsupported(97);
81    pub const PPMD: Self = CompressionMethod::Unsupported(98);
82    #[cfg(feature = "aes-crypto")]
83    pub const AES: Self = CompressionMethod::Aes;
84    #[cfg(not(feature = "aes-crypto"))]
85    pub const AES: Self = CompressionMethod::Unsupported(99);
86}
87impl CompressionMethod {
88    /// Converts an u16 to its corresponding CompressionMethod
89    #[deprecated(
90        since = "0.5.7",
91        note = "use a constant to construct a compression method"
92    )]
93    pub fn from_u16(val: u16) -> CompressionMethod {
94        #[allow(deprecated)]
95        match val {
96            0 => CompressionMethod::Stored,
97            #[cfg(any(
98                feature = "deflate",
99                feature = "deflate-miniz",
100                feature = "deflate-zlib"
101            ))]
102            8 => CompressionMethod::Deflated,
103            #[cfg(feature = "bzip2")]
104            12 => CompressionMethod::Bzip2,
105            #[cfg(feature = "zstd")]
106            93 => CompressionMethod::Zstd,
107            #[cfg(feature = "aes-crypto")]
108            99 => CompressionMethod::Aes,
109
110            v => CompressionMethod::Unsupported(v),
111        }
112    }
113
114    /// Converts a CompressionMethod to a u16
115    #[deprecated(
116        since = "0.5.7",
117        note = "to match on other compression methods, use a constant"
118    )]
119    pub fn to_u16(self) -> u16 {
120        #[allow(deprecated)]
121        match self {
122            CompressionMethod::Stored => 0,
123            #[cfg(any(
124                feature = "deflate",
125                feature = "deflate-miniz",
126                feature = "deflate-zlib"
127            ))]
128            CompressionMethod::Deflated => 8,
129            #[cfg(feature = "bzip2")]
130            CompressionMethod::Bzip2 => 12,
131            #[cfg(feature = "aes-crypto")]
132            CompressionMethod::Aes => 99,
133            #[cfg(feature = "zstd")]
134            CompressionMethod::Zstd => 93,
135
136            CompressionMethod::Unsupported(v) => v,
137        }
138    }
139}
140
141impl fmt::Display for CompressionMethod {
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        // Just duplicate what the Debug format looks like, i.e, the enum key:
144        write!(f, "{:?}", self)
145    }
146}
147
148/// The compression methods which have been implemented.
149pub const SUPPORTED_COMPRESSION_METHODS: &[CompressionMethod] = &[
150    CompressionMethod::Stored,
151    #[cfg(any(
152        feature = "deflate",
153        feature = "deflate-miniz",
154        feature = "deflate-zlib"
155    ))]
156    CompressionMethod::Deflated,
157    #[cfg(feature = "bzip2")]
158    CompressionMethod::Bzip2,
159    #[cfg(feature = "zstd")]
160    CompressionMethod::Zstd,
161];
162
163#[cfg(test)]
164mod test {
165    use super::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS};
166
167    #[test]
168    fn from_eq_to() {
169        for v in 0..(u16::MAX as u32 + 1) {
170            #[allow(deprecated)]
171            let from = CompressionMethod::from_u16(v as u16);
172            #[allow(deprecated)]
173            let to = from.to_u16() as u32;
174            assert_eq!(v, to);
175        }
176    }
177
178    #[test]
179    fn to_eq_from() {
180        fn check_match(method: CompressionMethod) {
181            #[allow(deprecated)]
182            let to = method.to_u16();
183            #[allow(deprecated)]
184            let from = CompressionMethod::from_u16(to);
185            #[allow(deprecated)]
186            let back = from.to_u16();
187            assert_eq!(to, back);
188        }
189
190        for &method in SUPPORTED_COMPRESSION_METHODS {
191            check_match(method);
192        }
193    }
194
195    #[test]
196    fn to_display_fmt() {
197        fn check_match(method: CompressionMethod) {
198            let debug_str = format!("{:?}", method);
199            let display_str = format!("{}", method);
200            assert_eq!(debug_str, display_str);
201        }
202
203        for &method in SUPPORTED_COMPRESSION_METHODS {
204            check_match(method);
205        }
206    }
207}