use crate::NippyJarError;
use serde::{Deserialize, Serialize};
mod zstd;
pub use self::zstd::{DecoderDictionary, Decompressor, Zstd, ZstdState};
mod lz4;
pub use self::lz4::Lz4;
pub trait Compression: Serialize + for<'a> Deserialize<'a> {
fn decompress_to(&self, value: &[u8], dest: &mut Vec<u8>) -> Result<(), NippyJarError>;
fn decompress(&self, value: &[u8]) -> Result<Vec<u8>, NippyJarError>;
fn compress_to(&self, src: &[u8], dest: &mut Vec<u8>) -> Result<usize, NippyJarError>;
fn compress(&self, src: &[u8]) -> Result<Vec<u8>, NippyJarError>;
fn is_ready(&self) -> bool {
true
}
#[cfg(test)]
fn prepare_compression(
&mut self,
_columns: Vec<impl IntoIterator<Item = Vec<u8>>>,
) -> Result<(), NippyJarError> {
Ok(())
}
}
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(test, derive(PartialEq))]
pub enum Compressors {
Zstd(Zstd),
Lz4(Lz4),
}
impl Compression for Compressors {
fn decompress_to(&self, value: &[u8], dest: &mut Vec<u8>) -> Result<(), NippyJarError> {
match self {
Self::Zstd(zstd) => zstd.decompress_to(value, dest),
Self::Lz4(lz4) => lz4.decompress_to(value, dest),
}
}
fn decompress(&self, value: &[u8]) -> Result<Vec<u8>, NippyJarError> {
match self {
Self::Zstd(zstd) => zstd.decompress(value),
Self::Lz4(lz4) => lz4.decompress(value),
}
}
fn compress_to(&self, src: &[u8], dest: &mut Vec<u8>) -> Result<usize, NippyJarError> {
let initial_capacity = dest.capacity();
loop {
let result = match self {
Self::Zstd(zstd) => zstd.compress_to(src, dest),
Self::Lz4(lz4) => lz4.compress_to(src, dest),
};
match result {
Ok(v) => return Ok(v),
Err(err) => match err {
NippyJarError::OutputTooSmall => {
dest.reserve(initial_capacity);
}
_ => return Err(err),
},
}
}
}
fn compress(&self, src: &[u8]) -> Result<Vec<u8>, NippyJarError> {
match self {
Self::Zstd(zstd) => zstd.compress(src),
Self::Lz4(lz4) => lz4.compress(src),
}
}
fn is_ready(&self) -> bool {
match self {
Self::Zstd(zstd) => zstd.is_ready(),
Self::Lz4(lz4) => lz4.is_ready(),
}
}
#[cfg(test)]
fn prepare_compression(
&mut self,
columns: Vec<impl IntoIterator<Item = Vec<u8>>>,
) -> Result<(), NippyJarError> {
match self {
Self::Zstd(zstd) => zstd.prepare_compression(columns),
Self::Lz4(lz4) => lz4.prepare_compression(columns),
}
}
}