use super::{CompressionError, Compressor};
#[derive(Debug, Clone)]
pub struct ZstdCompressor {
level: i32,
}
impl ZstdCompressor {
pub fn new() -> Self {
Self { level: 3 }
}
pub fn with_level(level: i32) -> Self {
Self { level }
}
pub fn level(&self) -> i32 {
self.level
}
}
impl Default for ZstdCompressor {
fn default() -> Self {
Self::new()
}
}
impl Compressor for ZstdCompressor {
fn compress(&self, data: &[u8]) -> Result<Vec<u8>, CompressionError> {
zstd::encode_all(data, self.level)
.map_err(|e| CompressionError::CompressionFailed(e.to_string()))
}
fn decompress(&self, compressed: &[u8]) -> Result<Vec<u8>, CompressionError> {
zstd::decode_all(compressed)
.map_err(|e| CompressionError::DecompressionFailed(e.to_string()))
}
fn name(&self) -> &'static str {
"zstd"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_zstd_compress_decompress() {
let compressor = ZstdCompressor::new();
let data = b"Hello, World! This is test data for Zstd compression.";
let compressed = compressor.compress(data).unwrap();
let decompressed = compressor.decompress(&compressed).unwrap();
assert_eq!(data, decompressed.as_slice());
}
#[test]
fn test_zstd_compression_ratio() {
let compressor = ZstdCompressor::new();
let data = b"A".repeat(1000);
let compressed = compressor.compress(&data).unwrap();
assert!(compressed.len() < data.len() / 10);
}
#[test]
fn test_zstd_with_level() {
let low_compression = ZstdCompressor::with_level(1);
let high_compression = ZstdCompressor::with_level(19);
let data = b"Test data for compression level comparison.".repeat(10);
let low_compressed = low_compression.compress(&data).unwrap();
let high_compressed = high_compression.compress(&data).unwrap();
assert!(high_compressed.len() <= low_compressed.len());
assert_eq!(low_compression.decompress(&low_compressed).unwrap(), data);
assert_eq!(high_compression.decompress(&high_compressed).unwrap(), data);
}
#[test]
fn test_zstd_empty_data() {
let compressor = ZstdCompressor::new();
let data = b"";
let compressed = compressor.compress(data).unwrap();
let decompressed = compressor.decompress(&compressed).unwrap();
assert_eq!(data, decompressed.as_slice());
}
#[test]
fn test_zstd_large_data() {
let compressor = ZstdCompressor::new();
let data = vec![b'X'; 100_000];
let compressed = compressor.compress(&data).unwrap();
let decompressed = compressor.decompress(&compressed).unwrap();
assert_eq!(data, decompressed);
assert!(compressed.len() < 1000);
}
#[test]
fn test_zstd_name() {
let compressor = ZstdCompressor::new();
assert_eq!(compressor.name(), "zstd");
}
#[test]
fn test_zstd_level_getter() {
let compressor = ZstdCompressor::with_level(9);
assert_eq!(compressor.level(), 9);
}
#[test]
fn test_zstd_default() {
let compressor = ZstdCompressor::default();
assert_eq!(compressor.level(), 3);
}
}