pub trait CompressionAlgorithm: Send + Sync {
// Required methods
fn name(&self) -> &'static str;
fn metadata(&self) -> PluginMetadata;
fn compress(
&self,
input: &[u8],
cancel_flag: Arc<AtomicBool>,
) -> Result<Vec<u8>>;
fn decompress(
&self,
input: &[u8],
cancel_flag: Arc<AtomicBool>,
) -> Result<Vec<u8>>;
fn detect(&self, file_header: &[u8]) -> bool;
}Expand description
Trait that all compression plugins must implement
Plugins provide compress/decompress operations with cooperative cancellation support.
The cancel_flag parameter allows the library to signal timeout or user cancellation,
and plugins SHOULD check this flag periodically (e.g., every block) and return early if set.
§Safety and Error Handling
- All methods return
Result<T>to enable proper error propagation - Plugins MUST NOT panic - all errors should be returned via
Result - Plugins MUST validate input data before processing
- If
cancel_flagis set totrue, plugins SHOULD returnErr(PluginError::Cancelled)
§Example Implementation
use crush_core::plugin::{CompressionAlgorithm, PluginMetadata, COMPRESSION_ALGORITHMS};
use crush_core::error::Result;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use linkme::distributed_slice;
struct MyPlugin;
impl CompressionAlgorithm for MyPlugin {
fn name(&self) -> &'static str { "my_plugin" }
fn metadata(&self) -> PluginMetadata {
PluginMetadata {
name: "my_plugin",
version: "1.0.0",
magic_number: [0x43, 0x52, 0x01, 0x10],
throughput: 500.0,
compression_ratio: 0.65,
description: "My compression algorithm",
}
}
fn compress(&self, input: &[u8], cancel_flag: Arc<AtomicBool>) -> Result<Vec<u8>> {
let mut output = Vec::new();
for chunk in input.chunks(4096) {
// Check cancellation flag periodically
if cancel_flag.load(Ordering::Acquire) {
return Err(crush_core::error::PluginError::Cancelled.into());
}
// Compress chunk...
}
Ok(output)
}
fn decompress(&self, input: &[u8], cancel_flag: Arc<AtomicBool>) -> Result<Vec<u8>> {
// Similar implementation with cancellation checking
Ok(vec![])
}
fn detect(&self, file_header: &[u8]) -> bool {
file_header.len() >= 4 && file_header[0..4] == self.metadata().magic_number
}
}
// Register plugin at compile-time
#[distributed_slice(COMPRESSION_ALGORITHMS)]
static MY_PLUGIN: &dyn CompressionAlgorithm = &MyPlugin;Required Methods§
Sourcefn metadata(&self) -> PluginMetadata
fn metadata(&self) -> PluginMetadata
Plugin metadata (performance characteristics and identification)
Sourcefn compress(
&self,
input: &[u8],
cancel_flag: Arc<AtomicBool>,
) -> Result<Vec<u8>>
fn compress( &self, input: &[u8], cancel_flag: Arc<AtomicBool>, ) -> Result<Vec<u8>>
Compress input data
§Parameters
input: Raw uncompressed data to compresscancel_flag: Atomic flag for cooperative cancellation Plugins SHOULD checkcancel_flag.load(Ordering::Acquire)periodically and returnErr(PluginError::Cancelled)if set totrue
§Returns
Compressed data without any header (header is added by the library)
§Errors
PluginError::Cancelledifcancel_flagis setPluginError::OperationFailedfor compression errorsValidationError::CorruptedDataif input is invalid
Sourcefn decompress(
&self,
input: &[u8],
cancel_flag: Arc<AtomicBool>,
) -> Result<Vec<u8>>
fn decompress( &self, input: &[u8], cancel_flag: Arc<AtomicBool>, ) -> Result<Vec<u8>>
Decompress compressed data
§Parameters
input: Compressed data (without Crush header, header already removed by library)cancel_flag: Atomic flag for cooperative cancellation
§Returns
Original uncompressed data
§Errors
PluginError::Cancelledifcancel_flagis setPluginError::OperationFailedfor decompression errorsValidationError::CorruptedDataif compressed data is invalid
Sourcefn detect(&self, file_header: &[u8]) -> bool
fn detect(&self, file_header: &[u8]) -> bool
Detect if this plugin can handle the given file header
This method determines if the plugin supports compressing a particular file type. Implementation is plugin-specific and may check:
- File extension (if passed as metadata)
- Magic bytes at the start of the file
- Content analysis
For decompression routing, the library uses the magic number in the Crush header, so this method is primarily for compression-time file type detection.
§Parameters
file_header: First bytes of the file (typically 512-4096 bytes)
§Returns
true if this plugin can compress this file type, false otherwise
§Performance Note
This method should execute in sub-millisecond time as it may be called for every plugin during file type detection.