sevenz_rust2/
method_options.rs

1#[cfg(feature = "compress")]
2use lzma_rust2::LZMA2Options;
3
4#[cfg(feature = "aes256")]
5use crate::aes256sha256::AesEncoderOptions;
6#[cfg(feature = "ppmd")]
7use ppmd_rust::{PPMD7_MAX_MEM_SIZE, PPMD7_MAX_ORDER, PPMD7_MIN_MEM_SIZE, PPMD7_MIN_ORDER};
8use std::fmt::Debug;
9
10#[cfg(feature = "bzip2")]
11#[cfg_attr(docsrs, doc(cfg(feature = "bzip2")))]
12#[derive(Debug, Copy, Clone)]
13pub struct Bzip2Options(pub(crate) u32);
14
15#[cfg(feature = "bzip2")]
16impl Bzip2Options {
17    pub const fn from_level(level: u32) -> Self {
18        Self(level)
19    }
20}
21
22#[cfg(feature = "bzip2")]
23impl Default for Bzip2Options {
24    fn default() -> Self {
25        Self(6)
26    }
27}
28
29#[cfg(feature = "brotli")]
30const MINIMAL_SKIPPABLE_FRAME_SIZE: u32 = 64 * 1024;
31#[cfg(feature = "brotli")]
32const DEFAULT_SKIPPABLE_FRAME_SIZE: u32 = 128 * 1024;
33
34#[cfg(feature = "brotli")]
35#[cfg_attr(docsrs, doc(cfg(feature = "brotli")))]
36#[derive(Debug, Copy, Clone)]
37pub struct BrotliOptions {
38    pub(crate) quality: u32,
39    pub(crate) window: u32,
40    pub(crate) skippable_frame_size: u32,
41}
42
43#[cfg(feature = "brotli")]
44impl BrotliOptions {
45    pub const fn from_quality_window(quality: u32, window: u32) -> Self {
46        let quality = if quality > 11 { 11 } else { quality };
47        let window = if window > 24 { 24 } else { window };
48        Self {
49            quality,
50            window,
51            skippable_frame_size: DEFAULT_SKIPPABLE_FRAME_SIZE,
52        }
53    }
54
55    /// Set's the skippable frame size. The size is defined as the size of uncompressed data a frame
56    /// contains. A value of 0 deactivates skippable frames and uses the native brotli bitstream.
57    /// If a value is set, then a similar skippable frame format used by LZ4 and ZSTD is used.
58    ///
59    /// Af value between 1..=64KiB will be set to 64KiB.
60    ///
61    /// This was first implemented by zstdmt. The default value is 128 KiB.
62    pub fn with_skippable_frame_size(mut self, skippable_frame_size: u32) -> Self {
63        if skippable_frame_size == 0 {
64            self.skippable_frame_size = 0;
65        } else if skippable_frame_size < MINIMAL_SKIPPABLE_FRAME_SIZE {
66            self.skippable_frame_size = MINIMAL_SKIPPABLE_FRAME_SIZE;
67        } else {
68            self.skippable_frame_size = skippable_frame_size;
69        }
70
71        self
72    }
73}
74
75#[cfg(feature = "brotli")]
76impl Default for BrotliOptions {
77    fn default() -> Self {
78        Self {
79            quality: 11,
80            window: 22,
81            skippable_frame_size: DEFAULT_SKIPPABLE_FRAME_SIZE,
82        }
83    }
84}
85
86#[cfg(feature = "compress")]
87#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
88#[derive(Debug, Copy, Clone)]
89pub struct DeltaOptions(pub(crate) u32);
90
91#[cfg(feature = "compress")]
92impl DeltaOptions {
93    pub const fn from_distance(distance: u32) -> Self {
94        let distance = if distance == 0 {
95            1
96        } else if distance > 256 {
97            256
98        } else {
99            distance
100        };
101        Self(distance)
102    }
103}
104
105#[cfg(feature = "compress")]
106impl Default for DeltaOptions {
107    fn default() -> Self {
108        Self(1)
109    }
110}
111
112#[cfg(feature = "deflate")]
113#[cfg_attr(docsrs, doc(cfg(feature = "deflate")))]
114#[derive(Debug, Copy, Clone)]
115pub struct DeflateOptions(pub(crate) u32);
116
117#[cfg(feature = "deflate")]
118impl DeflateOptions {
119    pub const fn from_level(level: u32) -> Self {
120        let level = if level > 9 { 9 } else { level };
121        Self(level)
122    }
123}
124
125#[cfg(feature = "deflate")]
126impl Default for DeflateOptions {
127    fn default() -> Self {
128        Self(6)
129    }
130}
131
132#[cfg(feature = "ppmd")]
133#[cfg_attr(docsrs, doc(cfg(feature = "ppmd")))]
134#[derive(Debug, Copy, Clone)]
135pub struct PPMDOptions {
136    pub(crate) order: u32,
137    pub(crate) memory_size: u32,
138}
139
140#[cfg(feature = "ppmd")]
141impl PPMDOptions {
142    pub const fn from_level(level: u32) -> Self {
143        const ORDERS: [u32; 10] = [3, 4, 4, 5, 5, 6, 8, 16, 24, 32];
144
145        let level = if level > 9 { 9 } else { level };
146        let order = ORDERS[level as usize];
147        let memory_size = 1 << (level + 19);
148
149        Self { order, memory_size }
150    }
151
152    pub const fn from_order_memory_size(order: u32, memory_size: u32) -> Self {
153        let order = if order > PPMD7_MAX_ORDER {
154            PPMD7_MAX_ORDER
155        } else if order < PPMD7_MIN_ORDER {
156            PPMD7_MIN_ORDER
157        } else {
158            order
159        };
160        let memory_size = if memory_size > PPMD7_MAX_MEM_SIZE {
161            PPMD7_MAX_MEM_SIZE
162        } else if memory_size < PPMD7_MIN_MEM_SIZE {
163            PPMD7_MIN_MEM_SIZE
164        } else {
165            memory_size
166        };
167        Self { order, memory_size }
168    }
169}
170
171#[cfg(feature = "ppmd")]
172impl Default for PPMDOptions {
173    fn default() -> Self {
174        Self::from_level(6)
175    }
176}
177
178#[cfg(feature = "zstd")]
179#[cfg_attr(docsrs, doc(cfg(feature = "zstd")))]
180#[derive(Debug, Copy, Clone)]
181pub struct ZStandardOptions(pub(crate) u32);
182
183#[cfg(feature = "zstd")]
184impl ZStandardOptions {
185    pub const fn from_level(level: u32) -> Self {
186        let level = if level > 22 { 22 } else { level };
187        Self(level)
188    }
189}
190
191#[cfg(feature = "zstd")]
192impl Default for ZStandardOptions {
193    fn default() -> Self {
194        Self(3)
195    }
196}
197
198#[derive(Debug, Clone)]
199pub enum MethodOptions {
200    Num(u32),
201    #[cfg(feature = "compress")]
202    #[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
203    Delta(DeltaOptions),
204    #[cfg(feature = "compress")]
205    #[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
206    LZMA2(LZMA2Options),
207    #[cfg(feature = "brotli")]
208    #[cfg_attr(docsrs, doc(cfg(feature = "brotli")))]
209    BROTLI(BrotliOptions),
210    #[cfg(feature = "bzip2")]
211    #[cfg_attr(docsrs, doc(cfg(feature = "bzip2")))]
212    BZIP2(Bzip2Options),
213    #[cfg(feature = "deflate")]
214    #[cfg_attr(docsrs, doc(cfg(feature = "deflate")))]
215    DEFLATE(DeflateOptions),
216    #[cfg(feature = "ppmd")]
217    #[cfg_attr(docsrs, doc(cfg(feature = "ppmd")))]
218    PPMD(PPMDOptions),
219    #[cfg(feature = "zstd")]
220    #[cfg_attr(docsrs, doc(cfg(feature = "zstd")))]
221    ZSTD(ZStandardOptions),
222    #[cfg(feature = "aes256")]
223    #[cfg_attr(docsrs, doc(cfg(feature = "aes256")))]
224    Aes(AesEncoderOptions),
225}
226
227#[cfg(feature = "aes256")]
228impl From<AesEncoderOptions> for MethodOptions {
229    fn from(value: AesEncoderOptions) -> Self {
230        Self::Aes(value)
231    }
232}
233
234#[cfg(feature = "aes256")]
235impl From<AesEncoderOptions> for crate::SevenZMethodConfiguration {
236    fn from(value: AesEncoderOptions) -> Self {
237        Self::new(crate::SevenZMethod::AES256SHA256).with_options(MethodOptions::Aes(value))
238    }
239}
240
241#[cfg(feature = "compress")]
242impl From<DeltaOptions> for crate::SevenZMethodConfiguration {
243    fn from(options: DeltaOptions) -> Self {
244        Self::new(crate::SevenZMethod::DELTA_FILTER).with_options(MethodOptions::Delta(options))
245    }
246}
247
248#[cfg(feature = "compress")]
249impl From<LZMA2Options> for crate::SevenZMethodConfiguration {
250    fn from(options: LZMA2Options) -> Self {
251        Self::new(crate::SevenZMethod::LZMA2).with_options(MethodOptions::LZMA2(options))
252    }
253}
254
255#[cfg(feature = "bzip2")]
256impl From<Bzip2Options> for crate::SevenZMethodConfiguration {
257    fn from(options: Bzip2Options) -> Self {
258        Self::new(crate::SevenZMethod::BZIP2).with_options(MethodOptions::BZIP2(options))
259    }
260}
261
262#[cfg(feature = "brotli")]
263impl From<BrotliOptions> for crate::SevenZMethodConfiguration {
264    fn from(options: BrotliOptions) -> Self {
265        Self::new(crate::SevenZMethod::BROTLI).with_options(MethodOptions::BROTLI(options))
266    }
267}
268
269#[cfg(feature = "deflate")]
270impl From<DeflateOptions> for crate::SevenZMethodConfiguration {
271    fn from(options: DeflateOptions) -> Self {
272        Self::new(crate::SevenZMethod::DEFLATE).with_options(MethodOptions::DEFLATE(options))
273    }
274}
275
276#[cfg(feature = "ppmd")]
277impl From<PPMDOptions> for crate::SevenZMethodConfiguration {
278    fn from(options: PPMDOptions) -> Self {
279        Self::new(crate::SevenZMethod::PPMD).with_options(MethodOptions::PPMD(options))
280    }
281}
282
283#[cfg(feature = "zstd")]
284impl From<ZStandardOptions> for crate::SevenZMethodConfiguration {
285    fn from(options: ZStandardOptions) -> Self {
286        Self::new(crate::SevenZMethod::ZSTD).with_options(MethodOptions::ZSTD(options))
287    }
288}
289
290impl From<u32> for MethodOptions {
291    fn from(n: u32) -> Self {
292        Self::Num(n)
293    }
294}
295
296#[cfg(feature = "compress")]
297impl From<DeltaOptions> for MethodOptions {
298    fn from(o: DeltaOptions) -> Self {
299        Self::Delta(o)
300    }
301}
302
303#[cfg(feature = "compress")]
304impl From<LZMA2Options> for MethodOptions {
305    fn from(o: LZMA2Options) -> Self {
306        Self::LZMA2(o)
307    }
308}
309
310#[cfg(feature = "bzip2")]
311impl From<Bzip2Options> for MethodOptions {
312    fn from(o: Bzip2Options) -> Self {
313        Self::BZIP2(o)
314    }
315}
316
317#[cfg(feature = "brotli")]
318impl From<BrotliOptions> for MethodOptions {
319    fn from(o: BrotliOptions) -> Self {
320        Self::BROTLI(o)
321    }
322}
323
324#[cfg(feature = "deflate")]
325impl From<DeflateOptions> for MethodOptions {
326    fn from(o: DeflateOptions) -> Self {
327        Self::DEFLATE(o)
328    }
329}
330
331#[cfg(feature = "ppmd")]
332impl From<PPMDOptions> for MethodOptions {
333    fn from(o: PPMDOptions) -> Self {
334        Self::PPMD(o)
335    }
336}
337
338#[cfg(feature = "zstd")]
339impl From<ZStandardOptions> for MethodOptions {
340    fn from(o: ZStandardOptions) -> Self {
341        Self::ZSTD(o)
342    }
343}
344
345impl MethodOptions {
346    pub fn get_lzma2_dict_size(&self) -> u32 {
347        match self {
348            MethodOptions::Num(n) => *n,
349            #[cfg(feature = "compress")]
350            MethodOptions::LZMA2(o) => o.dict_size,
351            #[allow(unused)]
352            _ => 0,
353        }
354    }
355}