use crate::Blob;
use anyhow::Result;
use brotli::{BrotliCompress, BrotliDecompress, enc::BrotliEncoderParams};
use std::io::Cursor;
use versatiles_derive::context;
#[context("Compressing blob ({} bytes) using Brotli with highest quality settings", blob.len())]
pub fn compress_brotli(blob: &Blob) -> Result<Blob> {
let params = BrotliEncoderParams {
quality: 10, lgwin: 19, size_hint: usize::try_from(blob.len())?,
..Default::default()
};
let mut input = Cursor::new(blob.as_slice());
let mut output = Vec::new();
BrotliCompress(&mut input, &mut output, ¶ms).context("Failed to compress data using Brotli")?;
Ok(Blob::from(output))
}
#[context("Compressing blob ({} bytes) using Brotli with fast compression settings", blob.len())]
pub fn compress_brotli_fast(blob: &Blob) -> Result<Blob> {
let params = BrotliEncoderParams {
quality: 3, lgwin: 16, size_hint: usize::try_from(blob.len())?,
..Default::default()
};
let mut input = Cursor::new(blob.as_slice());
let mut output = Vec::new();
BrotliCompress(&mut input, &mut output, ¶ms).context("Failed to compress data using Brotli (fast)")?;
Ok(Blob::from(output))
}
#[context("Decompressing blob ({} bytes) using Brotli", blob.len())]
pub fn decompress_brotli(blob: &Blob) -> Result<Blob> {
let mut cursor = Cursor::new(blob.as_slice());
let mut decompressed_data = Vec::new();
BrotliDecompress(&mut cursor, &mut decompressed_data).context("Failed to decompress data using Brotli")?;
Ok(Blob::from(decompressed_data))
}
#[cfg(test)]
mod tests {
use super::super::super::test_utils::generate_test_data;
use super::*;
#[test]
fn should_compress_and_decompress_brotli_correctly() -> Result<()> {
let data = generate_test_data(10_000);
let compressed = compress_brotli(&data)?;
let decompressed = decompress_brotli(&compressed)?;
assert_eq!(data, decompressed, "Brotli compression and decompression failed");
Ok(())
}
#[test]
fn should_compress_and_decompress_brotli_fast_correctly() -> Result<()> {
let data = generate_test_data(10_000);
let compressed = compress_brotli_fast(&data)?;
let decompressed = decompress_brotli(&compressed)?;
assert_eq!(data, decompressed, "Fast Brotli compression and decompression failed");
Ok(())
}
}