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