use std::io::{self, BufRead, Write};
use lazy_static::lazy_static;
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::support::un64;
pub trait FinishWrite: Write {
fn finish(&mut self) -> io::Result<()>;
}
impl<W: Write> FinishWrite for zstd::Encoder<W> {
fn finish(&mut self) -> io::Result<()> {
self.do_finish()
}
}
impl<W: FinishWrite + ?Sized> FinishWrite for Box<W> {
fn finish(&mut self) -> io::Result<()> {
(**self).finish()
}
}
#[derive(
Serialize_repr, Deserialize_repr, Clone, Copy, Debug, PartialEq, Eq,
)]
#[repr(u8)]
pub enum Compression {
Un64Zstd20200725 = 0,
Zstd = 1,
}
static ZSTD_DICT_20200725_RAW: &[u8] = include_bytes!("zstd-dict-20200725.dat");
lazy_static! {
static ref ZSTD_DICT_20200725_ENC: zstd::dict::EncoderDictionary<'static> =
zstd::dict::EncoderDictionary::new(ZSTD_DICT_20200725_RAW, 5);
static ref ZSTD_DICT_20200725_DEC: zstd::dict::DecoderDictionary<'static> =
zstd::dict::DecoderDictionary::new(ZSTD_DICT_20200725_RAW);
}
impl Compression {
pub const DEFAULT_FOR_MESSAGE: Self = Compression::Un64Zstd20200725;
pub const DEFAULT_FOR_STATE: Self = Compression::Zstd;
pub fn decompressor<'a>(
self,
reader: impl BufRead + 'a,
) -> io::Result<Box<dyn BufRead + 'a>> {
match self {
Compression::Un64Zstd20200725 => Ok(box_r(un64::Reader::new(
zstd::Decoder::with_prepared_dictionary(
reader,
&ZSTD_DICT_20200725_DEC,
)?,
))),
Compression::Zstd => {
Ok(box_r(io::BufReader::new(zstd::Decoder::new(reader)?)))
}
}
}
pub fn compressor<'a>(
self,
writer: impl Write + 'a,
) -> io::Result<impl FinishWrite + 'a> {
match self {
Compression::Un64Zstd20200725 => Ok(box_w(un64::Writer::new(
zstd::Encoder::with_prepared_dictionary(
writer,
&ZSTD_DICT_20200725_ENC,
)?,
))),
Compression::Zstd => Ok(box_w(zstd::Encoder::new(writer, 5)?)),
}
}
}
fn box_r<'a>(r: impl BufRead + 'a) -> Box<dyn BufRead + 'a> {
Box::new(r)
}
fn box_w<'a>(w: impl FinishWrite + 'a) -> Box<dyn FinishWrite + 'a> {
Box::new(w)
}