Coverage Report

Created: 2026-09-28 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}