this repo has no description
1mod brotli;
2mod bzip2;
3mod containers;
4mod gzip;
5mod lz4;
6mod lzma;
7mod pipeline;
8mod sevenz;
9mod snappy;
10mod stream;
11mod tar;
12mod xz;
13mod zip;
14mod zstd;
15
16pub use brotli::{Brotli, BrotliArgs};
17pub use bzip2::{Bzip2, Bzip2Args};
18pub use gzip::{Gzip, GzipArgs};
19pub use lz4::{Lz4, Lz4Args};
20pub use lzma::{Lzma, LzmaArgs};
21pub use pipeline::Pipeline;
22pub use sevenz::{SevenZ, SevenZArgs};
23pub use snappy::{Snappy, SnappyArgs};
24pub use tar::{Tar, TarArgs};
25pub use xz::{Xz, XzArgs};
26pub use zip::{Zip, ZipArgs};
27pub use zstd::{Zstd, ZstdArgs};
28
29use crate::utils::Compressor;
30
31/// Create a default compressor instance from an extension or name string.
32/// This is the single canonical lookup table for all compressor types.
33pub fn compressor_from_str(s: &str) -> Option<Box<dyn Compressor>> {
34 match s {
35 "tar" => Some(Box::<Tar>::default()),
36 "gzip" | "gz" => Some(Box::<Gzip>::default()),
37 "xz" => Some(Box::<Xz>::default()),
38 "bzip2" | "bz2" => Some(Box::<Bzip2>::default()),
39 "zip" => Some(Box::<Zip>::default()),
40 "zstd" | "zst" => Some(Box::<Zstd>::default()),
41 "lz4" => Some(Box::<Lz4>::default()),
42 "brotli" | "br" => Some(Box::<Brotli>::default()),
43 "snappy" | "sz" => Some(Box::<Snappy>::default()),
44 "lzma" => Some(Box::<Lzma>::default()),
45 "7z" | "sevenz" => Some(Box::<SevenZ>::default()),
46 _ => None,
47 }
48}
49
50/// Resolve an extension to a compressor chain in innermost→outermost order.
51/// Single-codec extensions (`gz`, `xz`, `tar`, …) produce a one-element chain;
52/// compound shortcut extensions (`tgz`, `tbz`, `tbz2`, `txz`, `tzst`) expand
53/// into the chain they represent (e.g. `tgz` → `[tar, gz]`).
54///
55/// This is the single source of truth for what any archive-like extension
56/// means. Both single extensions and compound shortcuts flow through here.
57pub fn chain_from_ext(ext: &str) -> Option<Vec<Box<dyn Compressor>>> {
58 match ext {
59 "tgz" => Some(vec![Box::<Tar>::default(), Box::<Gzip>::default()]),
60 "tbz" | "tbz2" => Some(vec![Box::<Tar>::default(), Box::<Bzip2>::default()]),
61 "txz" => Some(vec![Box::<Tar>::default(), Box::<Xz>::default()]),
62 "tzst" => Some(vec![Box::<Tar>::default(), Box::<Zstd>::default()]),
63 _ => compressor_from_str(ext).map(|c| vec![c]),
64 }
65}
66
67/// Resolve a dotted format string (e.g. `tar.gz`, `tgz`, `xz`) into a
68/// compressor chain. Every dot-separated segment is resolved via
69/// `chain_from_ext` and concatenated in order. Returns `None` if any
70/// segment isn't a known codec or shortcut.
71pub fn chain_from_format_str(s: &str) -> Option<Vec<Box<dyn Compressor>>> {
72 let mut chain = Vec::new();
73 for part in s.split('.') {
74 chain.extend(chain_from_ext(part)?);
75 }
76 if chain.is_empty() { None } else { Some(chain) }
77}