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 = "lz4")]
133#[cfg_attr(docsrs, doc(cfg(feature = "lz4")))]
134#[derive(Debug, Copy, Clone)]
135pub struct LZ4Options(pub(crate) u32);
136
137#[cfg(feature = "lz4")]
138impl LZ4Options {
139    pub const fn from_level(level: u32) -> Self {
140        let level = if level == 0 {
141            1
142        } else if level > 12 {
143            12
144        } else {
145            level
146        };
147        Self(level)
148    }
149}
150
151#[cfg(feature = "lz4")]
152impl Default for LZ4Options {
153    fn default() -> Self {
154        Self(1)
155    }
156}
157
158#[cfg(feature = "ppmd")]
159#[cfg_attr(docsrs, doc(cfg(feature = "ppmd")))]
160#[derive(Debug, Copy, Clone)]
161pub struct PPMDOptions {
162    pub(crate) order: u32,
163    pub(crate) memory_size: u32,
164}
165
166#[cfg(feature = "ppmd")]
167impl PPMDOptions {
168    pub const fn from_level(level: u32) -> Self {
169        const ORDERS: [u32; 10] = [3, 4, 4, 5, 5, 6, 8, 16, 24, 32];
170
171        let level = if level > 9 { 9 } else { level };
172        let order = ORDERS[level as usize];
173        let memory_size = 1 << (level + 19);
174
175        Self { order, memory_size }
176    }
177
178    pub const fn from_order_memory_size(order: u32, memory_size: u32) -> Self {
179        let order = if order > PPMD7_MAX_ORDER {
180            PPMD7_MAX_ORDER
181        } else if order < PPMD7_MIN_ORDER {
182            PPMD7_MIN_ORDER
183        } else {
184            order
185        };
186        let memory_size = if memory_size > PPMD7_MAX_MEM_SIZE {
187            PPMD7_MAX_MEM_SIZE
188        } else if memory_size < PPMD7_MIN_MEM_SIZE {
189            PPMD7_MIN_MEM_SIZE
190        } else {
191            memory_size
192        };
193        Self { order, memory_size }
194    }
195}
196
197#[cfg(feature = "ppmd")]
198impl Default for PPMDOptions {
199    fn default() -> Self {
200        Self::from_level(6)
201    }
202}
203
204#[cfg(feature = "zstd")]
205#[cfg_attr(docsrs, doc(cfg(feature = "zstd")))]
206#[derive(Debug, Copy, Clone)]
207pub struct ZStandardOptions(pub(crate) u32);
208
209#[cfg(feature = "zstd")]
210impl ZStandardOptions {
211    pub const fn from_level(level: u32) -> Self {
212        let level = if level > 22 { 22 } else { level };
213        Self(level)
214    }
215}
216
217#[cfg(feature = "zstd")]
218impl Default for ZStandardOptions {
219    fn default() -> Self {
220        Self(3)
221    }
222}
223
224#[derive(Debug, Clone)]
225pub enum MethodOptions {
226    Num(u32),
227    #[cfg(feature = "compress")]
228    #[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
229    Delta(DeltaOptions),
230    #[cfg(feature = "compress")]
231    #[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
232    LZMA2(LZMA2Options),
233    #[cfg(feature = "brotli")]
234    #[cfg_attr(docsrs, doc(cfg(feature = "brotli")))]
235    BROTLI(BrotliOptions),
236    #[cfg(feature = "bzip2")]
237    #[cfg_attr(docsrs, doc(cfg(feature = "bzip2")))]
238    BZIP2(Bzip2Options),
239    #[cfg(feature = "deflate")]
240    #[cfg_attr(docsrs, doc(cfg(feature = "deflate")))]
241    DEFLATE(DeflateOptions),
242    #[cfg(feature = "lz4")]
243    #[cfg_attr(docsrs, doc(cfg(feature = "lz4")))]
244    LZ4(LZ4Options),
245    #[cfg(feature = "ppmd")]
246    #[cfg_attr(docsrs, doc(cfg(feature = "ppmd")))]
247    PPMD(PPMDOptions),
248    #[cfg(feature = "zstd")]
249    #[cfg_attr(docsrs, doc(cfg(feature = "zstd")))]
250    ZSTD(ZStandardOptions),
251    #[cfg(feature = "aes256")]
252    #[cfg_attr(docsrs, doc(cfg(feature = "aes256")))]
253    Aes(AesEncoderOptions),
254}
255
256#[cfg(feature = "aes256")]
257impl From<AesEncoderOptions> for MethodOptions {
258    fn from(value: AesEncoderOptions) -> Self {
259        Self::Aes(value)
260    }
261}
262
263#[cfg(feature = "aes256")]
264impl From<AesEncoderOptions> for crate::SevenZMethodConfiguration {
265    fn from(value: AesEncoderOptions) -> Self {
266        Self::new(crate::SevenZMethod::AES256SHA256).with_options(MethodOptions::Aes(value))
267    }
268}
269
270#[cfg(feature = "compress")]
271impl From<DeltaOptions> for crate::SevenZMethodConfiguration {
272    fn from(options: DeltaOptions) -> Self {
273        Self::new(crate::SevenZMethod::DELTA_FILTER).with_options(MethodOptions::Delta(options))
274    }
275}
276
277#[cfg(feature = "compress")]
278impl From<LZMA2Options> for crate::SevenZMethodConfiguration {
279    fn from(options: LZMA2Options) -> Self {
280        Self::new(crate::SevenZMethod::LZMA2).with_options(MethodOptions::LZMA2(options))
281    }
282}
283
284#[cfg(feature = "bzip2")]
285impl From<Bzip2Options> for crate::SevenZMethodConfiguration {
286    fn from(options: Bzip2Options) -> Self {
287        Self::new(crate::SevenZMethod::BZIP2).with_options(MethodOptions::BZIP2(options))
288    }
289}
290
291#[cfg(feature = "brotli")]
292impl From<BrotliOptions> for crate::SevenZMethodConfiguration {
293    fn from(options: BrotliOptions) -> Self {
294        Self::new(crate::SevenZMethod::BROTLI).with_options(MethodOptions::BROTLI(options))
295    }
296}
297
298#[cfg(feature = "deflate")]
299impl From<DeflateOptions> for crate::SevenZMethodConfiguration {
300    fn from(options: DeflateOptions) -> Self {
301        Self::new(crate::SevenZMethod::DEFLATE).with_options(MethodOptions::DEFLATE(options))
302    }
303}
304
305#[cfg(feature = "lz4")]
306impl From<LZ4Options> for crate::SevenZMethodConfiguration {
307    fn from(options: LZ4Options) -> Self {
308        Self::new(crate::SevenZMethod::LZ4).with_options(MethodOptions::LZ4(options))
309    }
310}
311
312#[cfg(feature = "ppmd")]
313impl From<PPMDOptions> for crate::SevenZMethodConfiguration {
314    fn from(options: PPMDOptions) -> Self {
315        Self::new(crate::SevenZMethod::PPMD).with_options(MethodOptions::PPMD(options))
316    }
317}
318
319#[cfg(feature = "zstd")]
320impl From<ZStandardOptions> for crate::SevenZMethodConfiguration {
321    fn from(options: ZStandardOptions) -> Self {
322        Self::new(crate::SevenZMethod::ZSTD).with_options(MethodOptions::ZSTD(options))
323    }
324}
325
326impl From<u32> for MethodOptions {
327    fn from(n: u32) -> Self {
328        Self::Num(n)
329    }
330}
331
332#[cfg(feature = "compress")]
333impl From<DeltaOptions> for MethodOptions {
334    fn from(o: DeltaOptions) -> Self {
335        Self::Delta(o)
336    }
337}
338
339#[cfg(feature = "compress")]
340impl From<LZMA2Options> for MethodOptions {
341    fn from(o: LZMA2Options) -> Self {
342        Self::LZMA2(o)
343    }
344}
345
346#[cfg(feature = "bzip2")]
347impl From<Bzip2Options> for MethodOptions {
348    fn from(o: Bzip2Options) -> Self {
349        Self::BZIP2(o)
350    }
351}
352
353#[cfg(feature = "brotli")]
354impl From<BrotliOptions> for MethodOptions {
355    fn from(o: BrotliOptions) -> Self {
356        Self::BROTLI(o)
357    }
358}
359
360#[cfg(feature = "deflate")]
361impl From<DeflateOptions> for MethodOptions {
362    fn from(o: DeflateOptions) -> Self {
363        Self::DEFLATE(o)
364    }
365}
366
367#[cfg(feature = "lz4")]
368impl From<LZ4Options> for MethodOptions {
369    fn from(o: LZ4Options) -> Self {
370        Self::LZ4(o)
371    }
372}
373
374#[cfg(feature = "ppmd")]
375impl From<PPMDOptions> for MethodOptions {
376    fn from(o: PPMDOptions) -> Self {
377        Self::PPMD(o)
378    }
379}
380
381#[cfg(feature = "zstd")]
382impl From<ZStandardOptions> for MethodOptions {
383    fn from(o: ZStandardOptions) -> Self {
384        Self::ZSTD(o)
385    }
386}
387
388impl MethodOptions {
389    pub fn get_lzma2_dict_size(&self) -> u32 {
390        match self {
391            MethodOptions::Num(n) => *n,
392            #[cfg(feature = "compress")]
393            MethodOptions::LZMA2(o) => o.dict_size,
394            #[allow(unused)]
395            _ => 0,
396        }
397    }
398}