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}