pub trait Compressor:
Send
+ Sync
+ Debug {
// Required methods
fn id(&self) -> u8;
fn compress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>>;
fn decompress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>>;
fn compress_append(&self, data: &[u8], output: &mut Vec<u8>) -> Result<()>;
}Expand description
Interface for compression algorithms.
This trait defines the contract that all compression implementations must fulfill.
Each compressor is identified by a unique ID (0-7) that is stored in the chunk’s
MetaByte, allowing the reader to select the appropriate decompressor.
§Design
The trait provides three methods:
id: Returns the unique algorithm identifiercompress: Compresses data, returningCowfor zero-copy optimizationdecompress: Decompresses data, returningCowfor zero-copy when possiblecompress_append: Compresses directly into a buffer (avoids intermediate allocation)
§Thread Safety
Implementations must be Send + Sync to support parallel compression across multiple
threads. This is enforced by the trait bounds.
§Implementing Custom Compressors
To add a new compression algorithm:
use parcode::compression::Compressor;
use parcode::Result;
use std::borrow::Cow;
#[derive(Debug)]
struct MyCompressor;
impl Compressor for MyCompressor {
fn id(&self) -> u8 { 2 } // Use an available ID (2-7)
fn compress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>> {
// Implement compression logic
Ok(Cow::Borrowed(data))
}
fn decompress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>> {
// Implement decompression logic
Ok(Cow::Borrowed(data))
}
fn compress_append(&self, data: &[u8], output: &mut Vec<u8>) -> Result<()> {
// Implement direct-to-buffer compression
output.extend_from_slice(data);
Ok(())
}
}§Performance Notes
- The
compress_appendmethod is preferred during serialization as it avoids intermediate allocations - Returning
Cow::Borrowedfromcompresswhen compression doesn’t help enables zero-copy optimization
Required Methods§
Sourcefn id(&self) -> u8
fn id(&self) -> u8
Returns the unique ID stored in the MetaByte (Bits 1-3).
This ID must be in the range 0-7 (3 bits) and should be unique across all
registered compressors. ID 0 is reserved for NoCompression.
§ID Allocation
- 0:
NoCompression(reserved) - 1: LZ4 (reserved)
- 2-7: Available for custom algorithms
Sourcefn compress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>>
fn compress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>>
Compresses the input data.
Returns a Cow<[u8]> which may borrow the input if compression is not performed
or if the compressed size would be larger than the original (negative compression).
§Return Value
Cow::Borrowed(data): Compression was not beneficial or not performedCow::Owned(compressed): Data was successfully compressed
§Errors
Returns ParcodeError::Compression if the compression algorithm fails.
§Performance
This method may allocate memory for the compressed output. For better performance
during serialization, use compress_append instead.
Sourcefn decompress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>>
fn decompress<'a>(&self, data: &'a [u8]) -> Result<Cow<'a, [u8]>>
Decompresses the input data.
Returns a Cow<[u8]> containing the original uncompressed data.
§Return Value
Cow::Borrowed(data): No decompression needed (e.g.,NoCompression)Cow::Owned(decompressed): Data was successfully decompressed
§Errors
Returns ParcodeError::Compression if:
- The compressed data is corrupted
- The decompression algorithm fails
- The decompressed size exceeds expected bounds
Sourcefn compress_append(&self, data: &[u8], output: &mut Vec<u8>) -> Result<()>
fn compress_append(&self, data: &[u8], output: &mut Vec<u8>) -> Result<()>
Compresses data and appends it directly to the output vector.
This method is more efficient than compress during serialization
because it avoids intermediate allocations by writing directly to the final buffer.
§Parameters
data: The input data to compressoutput: The buffer to append compressed data to
§Errors
Returns ParcodeError::Compression if the compression algorithm fails.
§Performance
This is the preferred method for compression during serialization as it:
- Avoids intermediate allocations
- Writes directly to the final output buffer
- Reduces memory copies