/src/zip/src/compression.rs
Line | Count | Source |
1 | | //! Possible ZIP compression methods. |
2 | | |
3 | | use 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] |
15 | | pub 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 |
43 | | impl 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 | | } |
87 | | impl 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 | 290k | pub fn from_u16(val: u16) -> CompressionMethod { |
94 | | #[allow(deprecated)] |
95 | 290k | match val { |
96 | 77.5k | 0 => CompressionMethod::Stored, |
97 | | #[cfg(any( |
98 | | feature = "deflate", |
99 | | feature = "deflate-miniz", |
100 | | feature = "deflate-zlib" |
101 | | ))] |
102 | 54.5k | 8 => CompressionMethod::Deflated, |
103 | | #[cfg(feature = "bzip2")] |
104 | 1.85k | 12 => CompressionMethod::Bzip2, |
105 | | #[cfg(feature = "zstd")] |
106 | 19.8k | 93 => CompressionMethod::Zstd, |
107 | | #[cfg(feature = "aes-crypto")] |
108 | 696 | 99 => CompressionMethod::Aes, |
109 | | |
110 | 135k | v => CompressionMethod::Unsupported(v), |
111 | | } |
112 | 290k | } |
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 | 167k | pub fn to_u16(self) -> u16 { |
120 | | #[allow(deprecated)] |
121 | 167k | match self { |
122 | 56.2k | CompressionMethod::Stored => 0, |
123 | | #[cfg(any( |
124 | | feature = "deflate", |
125 | | feature = "deflate-miniz", |
126 | | feature = "deflate-zlib" |
127 | | ))] |
128 | 35.6k | CompressionMethod::Deflated => 8, |
129 | | #[cfg(feature = "bzip2")] |
130 | 7.54k | CompressionMethod::Bzip2 => 12, |
131 | | #[cfg(feature = "aes-crypto")] |
132 | 0 | CompressionMethod::Aes => 99, |
133 | | #[cfg(feature = "zstd")] |
134 | 67.8k | CompressionMethod::Zstd => 93, |
135 | | |
136 | 0 | CompressionMethod::Unsupported(v) => v, |
137 | | } |
138 | 167k | } |
139 | | } |
140 | | |
141 | | impl fmt::Display for CompressionMethod { |
142 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
143 | | // Just duplicate what the Debug format looks like, i.e, the enum key: |
144 | 0 | write!(f, "{self:?}") |
145 | 0 | } |
146 | | } |
147 | | |
148 | | /// The compression methods which have been implemented. |
149 | | pub 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)] |
164 | | mod 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 | | } |