use anyhow::Result;
use serde::{Deserialize, Serialize};
#[cfg(feature = "profile")]
use flamer::*;
#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub enum Compression {
NoCompression,
ZStd { level: i32 },
}
impl Compression {
#[cfg_attr(feature = "profile", flame)]
pub fn compress(self, data: Vec<u8>) -> Vec<u8> {
match self {
Compression::NoCompression => data,
Compression::ZStd { level } => {
let mut output = Vec::<u8>::with_capacity(data.len());
zstd::stream::copy_encode(data.as_slice(), &mut output, level).unwrap();
output
}
}
}
pub async fn compress_async(self, data: Vec<u8>) -> Vec<u8> {
self.compress(data)
}
#[cfg_attr(feature = "profile", flame)]
pub fn decompress(self, data: Vec<u8>) -> Result<Vec<u8>> {
match self {
Compression::NoCompression => Ok(data),
Compression::ZStd { .. } => {
let mut output = Vec::<u8>::new();
zstd::stream::copy_decode(data.as_slice(), &mut output)?;
Ok(output)
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str;
#[test]
fn test_zstd() {
let compression = Compression::ZStd { level: 6 };
let data_string =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
let data_bytes = data_string.as_bytes();
let compressed_bytes = compression.compress(data_bytes.to_vec());
let decompressed_bytes = compression.decompress(compressed_bytes.clone()).unwrap();
let decompressed_string = str::from_utf8(&decompressed_bytes).unwrap();
println!("Input string: {}", data_string);
println!("Input bytes: \n{:X?}", data_bytes);
println!("Original length: {}", data_bytes.len());
println!("Compressed bytes: \n{:X?}", compressed_bytes);
println!("Compressed length: {}", compressed_bytes.len());
println!("Decompressed bytes: \n{:X?}", decompressed_bytes);
println!("Decompressed string: {}", decompressed_string);
assert_eq!(data_string, decompressed_string);
}
}