mod core;
use crate::DataType;
#[cfg(feature = "compression")]
use alloc::vec::Vec;
use thiserror::Error;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Error)]
#[non_exhaustive]
pub enum CodecError {
#[error("{0}")]
Invalid(&'static str),
#[error("custom codec {0} is already registered")]
DuplicateId(u32),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Signature {
pub inputs: &'static [DataType],
pub variable_input: bool,
pub outputs: &'static [DataType],
pub variable_outputs: &'static [DataType],
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CodecInput<'a> {
pub data_type: DataType,
pub width: usize,
pub bytes: &'a [u8],
pub string_lengths: &'a [u32],
}
pub trait CustomCodec: Send + Sync + 'static {
fn signature(&self) -> Signature;
#[cfg(feature = "compression")]
fn encode(
&self,
cx: &mut EncoderContext<'_>,
inputs: &[CodecInput<'_>],
) -> Result<(), CodecError>;
#[cfg(feature = "decompression")]
fn decode(
&self,
cx: &mut DecoderContext<'_>,
inputs: &[CodecInput<'_>],
) -> Result<(), CodecError>;
}
#[cfg(feature = "compression")]
pub struct EncoderContext<'a> {
api: &'a mut dyn core::EncoderApi,
}
#[cfg(feature = "compression")]
impl ::core::fmt::Debug for EncoderContext<'_> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str("EncoderContext")
}
}
#[cfg(feature = "compression")]
impl EncoderContext<'_> {
pub fn level(&self) -> i32 {
self.api.level()
}
pub fn format_version(&self) -> u32 {
self.api.format_version()
}
pub fn local_int(&self, id: i32) -> Option<i32> {
self.api.local_int(id)
}
pub fn local_bytes(&self, id: i32) -> Option<&[u8]> {
self.api.local_bytes(id)
}
pub fn emit(
&mut self,
outcome: usize,
width: usize,
bytes: Vec<u8>,
) -> Result<usize, CodecError> {
self.api.emit(outcome, width, bytes)
}
pub fn emit_strings(
&mut self,
outcome: usize,
bytes: Vec<u8>,
lengths: Vec<u32>,
) -> Result<usize, CodecError> {
self.api.emit_strings(outcome, bytes, lengths)
}
pub fn send_header(&mut self, header: &[u8]) -> Result<(), CodecError> {
self.api.send_header(header)
}
}
#[cfg(feature = "decompression")]
#[derive(Debug)]
pub struct DecoderContext<'a> {
header: &'a [u8],
streams: &'a mut [crate::decompressor::core::data::Stream],
committed: alloc::boxed::Box<[bool]>,
budget: usize,
}
#[cfg(feature = "decompression")]
impl DecoderContext<'_> {
pub const fn header(&self) -> &[u8] {
self.header
}
pub const fn output_count(&self) -> usize {
self.streams.len()
}
pub const fn output_budget(&self) -> usize {
self.budget
}
pub fn emit(&mut self, index: usize, width: usize, bytes: &[u8]) -> Result<(), CodecError> {
core::emit(self, index, width, bytes)
}
pub fn emit_strings(
&mut self,
index: usize,
bytes: &[u8],
lengths: &[u32],
) -> Result<(), CodecError> {
core::emit_strings(self, index, bytes, lengths)
}
}
pub(crate) use core::*;