Skip to main content

haagenti_core/
traits.rs

1//! Core traits for compression and decompression.
2//!
3//! ## Trait Hierarchy
4//!
5//! ```text
6//! Compressor / Decompressor  (one-shot operations)
7//!       ↓
8//! StreamingCompressor / StreamingDecompressor  (incremental)
9//!       ↓
10//! Codec  (combined compress + decompress)
11//! ```
12
13use crate::error::Result;
14use crate::stats::CompressionStats;
15use crate::stream::Flush;
16use crate::types::{Algorithm, CompressionLevel, CompressionRatio};
17
18/// One-shot compression operations.
19pub trait Compressor {
20    /// Get the compression algorithm.
21    fn algorithm(&self) -> Algorithm;
22
23    /// Get the configured compression level.
24    fn level(&self) -> CompressionLevel;
25
26    /// Compress data in one shot.
27    ///
28    /// # Arguments
29    /// * `input` - Data to compress
30    ///
31    /// # Returns
32    /// Compressed data as a vector.
33    fn compress(&self, input: &[u8]) -> Result<Vec<u8>>;
34
35    /// Compress data into existing buffer.
36    ///
37    /// # Arguments
38    /// * `input` - Data to compress
39    /// * `output` - Buffer to write compressed data
40    ///
41    /// # Returns
42    /// Number of bytes written to output.
43    fn compress_to(&self, input: &[u8], output: &mut [u8]) -> Result<usize>;
44
45    /// Calculate maximum compressed size for input length.
46    /// Useful for pre-allocating output buffers.
47    fn max_compressed_size(&self, input_len: usize) -> usize;
48
49    /// Get compression statistics after operation.
50    fn stats(&self) -> Option<CompressionStats> {
51        None
52    }
53}
54
55/// One-shot decompression operations.
56pub trait Decompressor {
57    /// Get the decompression algorithm.
58    fn algorithm(&self) -> Algorithm;
59
60    /// Decompress data in one shot.
61    ///
62    /// # Arguments
63    /// * `input` - Compressed data
64    ///
65    /// # Returns
66    /// Decompressed data as a vector.
67    fn decompress(&self, input: &[u8]) -> Result<Vec<u8>>;
68
69    /// Decompress data into existing buffer.
70    ///
71    /// # Arguments
72    /// * `input` - Compressed data
73    /// * `output` - Buffer to write decompressed data
74    ///
75    /// # Returns
76    /// Number of bytes written to output.
77    fn decompress_to(&self, input: &[u8], output: &mut [u8]) -> Result<usize>;
78
79    /// Decompress with known output size (more efficient).
80    fn decompress_with_size(&self, input: &[u8], output_size: usize) -> Result<Vec<u8>> {
81        let mut output = vec![0u8; output_size];
82        let written = self.decompress_to(input, &mut output)?;
83        output.truncate(written);
84        Ok(output)
85    }
86
87    /// Get decompression statistics after operation.
88    fn stats(&self) -> Option<CompressionStats> {
89        None
90    }
91}
92
93/// Streaming compression for incremental processing.
94pub trait StreamingCompressor {
95    /// Get the compression algorithm.
96    fn algorithm(&self) -> Algorithm;
97
98    /// Begin a new compression stream.
99    fn begin(&mut self) -> Result<()>;
100
101    /// Compress a chunk of data.
102    ///
103    /// # Arguments
104    /// * `input` - Data chunk to compress
105    /// * `output` - Buffer for compressed output
106    /// * `flush` - Flush mode (None, Sync, or Finish)
107    ///
108    /// # Returns
109    /// Tuple of (bytes_read, bytes_written).
110    fn compress_chunk(
111        &mut self,
112        input: &[u8],
113        output: &mut [u8],
114        flush: Flush,
115    ) -> Result<(usize, usize)>;
116
117    /// Finish compression and flush remaining data.
118    ///
119    /// # Arguments
120    /// * `output` - Buffer for final compressed output
121    ///
122    /// # Returns
123    /// Number of bytes written.
124    fn finish(&mut self, output: &mut [u8]) -> Result<usize>;
125
126    /// Reset compressor state for reuse.
127    fn reset(&mut self);
128}
129
130/// Streaming decompression for incremental processing.
131pub trait StreamingDecompressor {
132    /// Get the decompression algorithm.
133    fn algorithm(&self) -> Algorithm;
134
135    /// Begin a new decompression stream.
136    fn begin(&mut self) -> Result<()>;
137
138    /// Decompress a chunk of data.
139    ///
140    /// # Arguments
141    /// * `input` - Compressed data chunk
142    /// * `output` - Buffer for decompressed output
143    ///
144    /// # Returns
145    /// Tuple of (bytes_read, bytes_written, is_finished).
146    fn decompress_chunk(&mut self, input: &[u8], output: &mut [u8])
147        -> Result<(usize, usize, bool)>;
148
149    /// Check if decompression is complete.
150    fn is_finished(&self) -> bool;
151
152    /// Reset decompressor state for reuse.
153    fn reset(&mut self);
154}
155
156/// Combined codec for both compression and decompression.
157pub trait Codec: Compressor + Decompressor {
158    /// Create a new codec with default settings.
159    fn new() -> Self
160    where
161        Self: Sized;
162
163    /// Create a new codec with specified level.
164    fn with_level(level: CompressionLevel) -> Self
165    where
166        Self: Sized;
167
168    /// Round-trip test: compress then decompress.
169    /// Returns true if data matches.
170    fn verify_roundtrip(&self, data: &[u8]) -> Result<bool> {
171        let compressed = self.compress(data)?;
172        let decompressed = self.decompress(&compressed)?;
173        Ok(data == decompressed.as_slice())
174    }
175
176    /// Get compression ratio for given data.
177    fn measure_ratio(&self, data: &[u8]) -> Result<CompressionRatio> {
178        let compressed = self.compress(data)?;
179        Ok(CompressionRatio::new(data.len(), compressed.len()))
180    }
181}
182
183/// Dictionary-based compression for improved ratios on similar data.
184pub trait DictionaryCompressor: Compressor {
185    /// Set compression dictionary.
186    fn set_dictionary(&mut self, dictionary: &[u8]) -> Result<()>;
187
188    /// Train dictionary from sample data.
189    fn train_dictionary(samples: &[&[u8]], dict_size: usize) -> Result<Vec<u8>>;
190
191    /// Clear current dictionary.
192    fn clear_dictionary(&mut self);
193}
194
195/// Dictionary-based decompression.
196pub trait DictionaryDecompressor: Decompressor {
197    /// Set decompression dictionary.
198    /// Must match the dictionary used for compression.
199    fn set_dictionary(&mut self, dictionary: &[u8]) -> Result<()>;
200
201    /// Clear current dictionary.
202    fn clear_dictionary(&mut self);
203}
204
205/// Parallel compression for multi-threaded environments.
206pub trait ParallelCompressor: Compressor {
207    /// Compress using multiple threads.
208    ///
209    /// # Arguments
210    /// * `input` - Data to compress
211    /// * `num_threads` - Number of threads to use (0 = auto-detect)
212    fn compress_parallel(&self, input: &[u8], num_threads: usize) -> Result<Vec<u8>>;
213
214    /// Set default thread count for parallel operations.
215    fn set_threads(&mut self, num_threads: usize);
216}
217
218/// SIMD-accelerated compression operations.
219pub trait SimdCompressor: Compressor {
220    /// Check if SIMD is available on current platform.
221    fn simd_available() -> bool;
222
223    /// Get SIMD feature level (e.g., "avx2", "avx512", "neon").
224    fn simd_level() -> &'static str;
225
226    /// Force SIMD on/off (for testing).
227    fn set_simd_enabled(&mut self, enabled: bool);
228}