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}
208