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 | 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 | |
141 | impl 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. |
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 | } |
208 | |