• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     )]
from_u16(val: u16) -> CompressionMethod93     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     )]
to_u16(self) -> u16119     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 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result142     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]
from_eq_to()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]
to_eq_from()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]
to_display_fmt()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