use crate::error::{CompressionError, Result};
use std::io::{Read, Write};
#[derive(Debug, Clone, Default)]
pub struct SnappyConfig {
pub framed: bool,
}
impl SnappyConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_framed(mut self, framed: bool) -> Self {
self.framed = framed;
self
}
}
pub struct SnappyCodec {
_config: SnappyConfig,
}
impl SnappyCodec {
pub fn new() -> Self {
Self {
_config: SnappyConfig::default(),
}
}
pub fn with_config(config: SnappyConfig) -> Self {
Self { _config: config }
}
pub fn compress(&self, input: &[u8]) -> Result<Vec<u8>> {
if input.is_empty() {
return Ok(Vec::new());
}
Ok(oxiarc_snappy::compress(input))
}
pub fn decompress(&self, input: &[u8]) -> Result<Vec<u8>> {
if input.is_empty() {
return Ok(Vec::new());
}
oxiarc_snappy::decompress(input).map_err(|e| CompressionError::SnappyError(e.to_string()))
}
pub fn compress_framed<R: Read, W: Write>(&self, mut reader: R, writer: W) -> Result<usize> {
let mut encoder = oxiarc_snappy::FrameEncoder::new(writer);
let bytes_written = std::io::copy(&mut reader, &mut encoder)?;
encoder
.finish()
.map_err(|e| CompressionError::SnappyError(e.to_string()))?;
Ok(bytes_written as usize)
}
pub fn decompress_framed<R: Read, W: Write>(&self, reader: R, mut writer: W) -> Result<usize> {
let mut decoder = oxiarc_snappy::FrameDecoder::new(reader);
let bytes_written = std::io::copy(&mut decoder, &mut writer)?;
Ok(bytes_written as usize)
}
pub fn max_compressed_size(input_size: usize) -> usize {
oxiarc_snappy::max_compress_len(input_size)
}
pub fn get_decompressed_size(input: &[u8]) -> Result<usize> {
if input.is_empty() {
return Ok(0);
}
let size = oxiarc_snappy::decompress_len(input)
.map_err(|e| CompressionError::SnappyError(e.to_string()))?;
Ok(size)
}
}
impl Default for SnappyCodec {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_snappy_compress_decompress() {
let codec = SnappyCodec::new();
let data = b"Hello, world! This is a test of Snappy compression.".repeat(100);
let compressed = codec.compress(&data).expect("Compression failed");
assert!(compressed.len() < data.len());
let decompressed = codec.decompress(&compressed).expect("Decompression failed");
assert_eq!(decompressed, data);
}
#[test]
fn test_snappy_empty_data() {
let codec = SnappyCodec::new();
let data: &[u8] = b"";
let compressed = codec.compress(data).expect("Compression failed");
assert_eq!(compressed.len(), 0);
let decompressed = codec.decompress(&compressed).expect("Decompression failed");
assert_eq!(decompressed.len(), 0);
}
#[test]
fn test_snappy_max_compressed_size() {
let size = SnappyCodec::max_compressed_size(1024);
assert!(size >= 1024);
}
#[test]
fn test_snappy_get_decompressed_size() {
let codec = SnappyCodec::new();
let data = b"Hello, world!".repeat(10);
let compressed = codec.compress(&data).expect("Compression failed");
let size = SnappyCodec::get_decompressed_size(&compressed).expect("Failed to get size");
assert_eq!(size, data.len());
}
}