use std::io::Result;
use zstd::stream::raw::Encoder;
use zstd::stream::raw::Operation;
use crate::axum_factory::compression::codec::Encode;
use crate::axum_factory::compression::unshared::Unshared;
use crate::axum_factory::compression::util::PartialBuffer;
#[derive(Debug)]
pub(crate) struct ZstdEncoder {
encoder: Unshared<Encoder<'static>>,
}
impl ZstdEncoder {
pub(crate) fn new(level: i32) -> Self {
Self {
encoder: Unshared::new(Encoder::new(level).unwrap()),
}
}
}
impl Encode for ZstdEncoder {
fn encode(
&mut self,
input: &mut PartialBuffer<impl AsRef<[u8]>>,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<()> {
let status = self
.encoder
.get_mut()
.run_on_buffers(input.unwritten(), output.unwritten_mut())?;
input.advance(status.bytes_read);
output.advance(status.bytes_written);
Ok(())
}
fn flush(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool> {
let mut out_buf = zstd_safe::OutBuffer::around(output.unwritten_mut());
let bytes_left = self.encoder.get_mut().flush(&mut out_buf)?;
let len = out_buf.as_slice().len();
output.advance(len);
Ok(bytes_left == 0)
}
fn finish(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool> {
let mut out_buf = zstd_safe::OutBuffer::around(output.unwritten_mut());
let bytes_left = self.encoder.get_mut().finish(&mut out_buf, true)?;
let len = out_buf.as_slice().len();
output.advance(len);
Ok(bytes_left == 0)
}
}