exarch_core/formats/
compression.rs

1//! Compression codec support for archive formats.
2//!
3//! This module provides unified handling of compression codecs used with
4//! TAR archives. The same compression codecs can be used for both reading
5//! (decompression) and writing (compression).
6//!
7//! # Supported Codecs
8//!
9//! - **Gzip** (.tar.gz, .tgz): Fast compression with good compatibility
10//! - **Bzip2** (.tar.bz2, .tbz2): Better compression ratio, slower
11//! - **Xz** (.tar.xz, .txz): Best compression ratio, slowest
12//! - **Zstd** (.tar.zst, .tzst): Modern codec with good speed/ratio balance
13
14/// Compression codec for archive files.
15///
16/// Represents the compression algorithm used for compressed archives.
17/// Each codec has different trade-offs between compression ratio,
18/// speed, and compatibility.
19///
20/// # Performance Characteristics
21///
22/// | Codec | Compression | Decompression | Ratio | Compatibility |
23/// |-------|-------------|---------------|-------|---------------|
24/// | Gzip  | Fast        | Fast          | Good  | Excellent     |
25/// | Bzip2 | Slow        | Medium        | Better| Good          |
26/// | Xz    | Very Slow   | Medium        | Best  | Good          |
27/// | Zstd  | Fast        | Very Fast     | Good  | Modern        |
28///
29/// # Examples
30///
31/// ```
32/// use exarch_core::formats::compression::CompressionCodec;
33///
34/// // Choose codec based on requirements
35/// let fast_codec = CompressionCodec::Gzip; // Fast compression
36/// let best_codec = CompressionCodec::Xz; // Best compression ratio
37/// let modern_codec = CompressionCodec::Zstd; // Modern balanced approach
38/// ```
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
40pub enum CompressionCodec {
41    /// Gzip compression (deflate algorithm).
42    ///
43    /// Fast compression and decompression with widespread support.
44    /// Good default choice for most use cases.
45    Gzip,
46
47    /// Bzip2 compression (Burrows-Wheeler algorithm).
48    ///
49    /// Better compression ratio than gzip but slower.
50    /// Good for archives that will be distributed.
51    Bzip2,
52
53    /// Xz compression (LZMA2 algorithm).
54    ///
55    /// Best compression ratio but slowest.
56    /// Good for long-term storage or bandwidth-constrained transfers.
57    Xz,
58
59    /// Zstd compression (Zstandard algorithm).
60    ///
61    /// Modern codec with excellent speed and good compression ratio.
62    /// Good for archives that need fast decompression.
63    Zstd,
64}
65
66impl CompressionCodec {
67    /// Returns the typical file extension for this codec when used with TAR.
68    ///
69    /// # Examples
70    ///
71    /// ```
72    /// use exarch_core::formats::compression::CompressionCodec;
73    ///
74    /// assert_eq!(CompressionCodec::Gzip.extension(), "tar.gz");
75    /// assert_eq!(CompressionCodec::Bzip2.extension(), "tar.bz2");
76    /// assert_eq!(CompressionCodec::Xz.extension(), "tar.xz");
77    /// assert_eq!(CompressionCodec::Zstd.extension(), "tar.zst");
78    /// ```
79    #[must_use]
80    pub const fn extension(self) -> &'static str {
81        match self {
82            Self::Gzip => "tar.gz",
83            Self::Bzip2 => "tar.bz2",
84            Self::Xz => "tar.xz",
85            Self::Zstd => "tar.zst",
86        }
87    }
88
89    /// Returns a human-readable name for this codec.
90    ///
91    /// # Examples
92    ///
93    /// ```
94    /// use exarch_core::formats::compression::CompressionCodec;
95    ///
96    /// assert_eq!(CompressionCodec::Gzip.name(), "gzip");
97    /// assert_eq!(CompressionCodec::Bzip2.name(), "bzip2");
98    /// ```
99    #[must_use]
100    pub const fn name(self) -> &'static str {
101        match self {
102            Self::Gzip => "gzip",
103            Self::Bzip2 => "bzip2",
104            Self::Xz => "xz",
105            Self::Zstd => "zstd",
106        }
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn test_codec_extension() {
116        assert_eq!(CompressionCodec::Gzip.extension(), "tar.gz");
117        assert_eq!(CompressionCodec::Bzip2.extension(), "tar.bz2");
118        assert_eq!(CompressionCodec::Xz.extension(), "tar.xz");
119        assert_eq!(CompressionCodec::Zstd.extension(), "tar.zst");
120    }
121
122    #[test]
123    fn test_codec_name() {
124        assert_eq!(CompressionCodec::Gzip.name(), "gzip");
125        assert_eq!(CompressionCodec::Bzip2.name(), "bzip2");
126        assert_eq!(CompressionCodec::Xz.name(), "xz");
127        assert_eq!(CompressionCodec::Zstd.name(), "zstd");
128    }
129
130    #[test]
131    fn test_codec_equality() {
132        assert_eq!(CompressionCodec::Gzip, CompressionCodec::Gzip);
133        assert_ne!(CompressionCodec::Gzip, CompressionCodec::Bzip2);
134    }
135
136    #[test]
137    fn test_codec_hash() {
138        use std::collections::HashSet;
139
140        let mut set = HashSet::new();
141        set.insert(CompressionCodec::Gzip);
142        set.insert(CompressionCodec::Bzip2);
143        set.insert(CompressionCodec::Gzip); // Duplicate
144
145        assert_eq!(set.len(), 2);
146        assert!(set.contains(&CompressionCodec::Gzip));
147        assert!(set.contains(&CompressionCodec::Bzip2));
148    }
149}