use super::*;
pub trait CodesReaderFactory<E: Endianness> {
type CodesReader<'a>
where
Self: 'a;
fn new_reader(&self) -> Self::CodesReader<'_>;
}
pub trait CodesReaderFactoryHelper<E: Endianness>:
for<'a> CodesReaderFactory<E, CodesReader<'a>: CodesRead<E, Error = Self::Error>>
{
type Error;
}
impl<E: Endianness, F, ERR> CodesReaderFactoryHelper<E> for F
where
F: ?Sized + for<'a> CodesReaderFactory<E, CodesReader<'a>: CodesRead<E, Error = ERR>>,
{
type Error = ERR;
}
type FactoryReadFn<E, CRF> = for<'a> fn(
&mut <CRF as CodesReaderFactory<E>>::CodesReader<'a>,
)
-> Result<u64, <CRF as CodesReaderFactoryHelper<E>>::Error>;
#[derive(Debug, Copy)]
pub struct FactoryFuncCodeReader<E: Endianness, CRF: CodesReaderFactoryHelper<E> + ?Sized>(
FactoryReadFn<E, CRF>,
);
impl<E: Endianness, CRF: CodesReaderFactoryHelper<E> + ?Sized> Clone
for FactoryFuncCodeReader<E, CRF>
{
#[inline(always)]
fn clone(&self) -> Self {
Self(self.0)
}
}
impl<E: Endianness, CRF: CodesReaderFactoryHelper<E> + ?Sized> FactoryFuncCodeReader<E, CRF> {
const UNARY: FactoryReadFn<E, CRF> = |reader| reader.read_unary();
const GAMMA: FactoryReadFn<E, CRF> = |reader| reader.read_gamma();
const DELTA: FactoryReadFn<E, CRF> = |reader| reader.read_delta();
const OMEGA: FactoryReadFn<E, CRF> = |reader| reader.read_omega();
const VBYTE_BE: FactoryReadFn<E, CRF> = |reader| reader.read_vbyte_be();
const VBYTE_LE: FactoryReadFn<E, CRF> = |reader| reader.read_vbyte_le();
const ZETA2: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(2);
const ZETA3: FactoryReadFn<E, CRF> = |reader| reader.read_zeta3();
const ZETA4: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(4);
const ZETA5: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(5);
const ZETA6: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(6);
const ZETA7: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(7);
const ZETA8: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(8);
const ZETA9: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(9);
const ZETA10: FactoryReadFn<E, CRF> = |reader| reader.read_zeta(10);
const RICE1: FactoryReadFn<E, CRF> = |reader| reader.read_rice(1);
const RICE2: FactoryReadFn<E, CRF> = |reader| reader.read_rice(2);
const RICE3: FactoryReadFn<E, CRF> = |reader| reader.read_rice(3);
const RICE4: FactoryReadFn<E, CRF> = |reader| reader.read_rice(4);
const RICE5: FactoryReadFn<E, CRF> = |reader| reader.read_rice(5);
const RICE6: FactoryReadFn<E, CRF> = |reader| reader.read_rice(6);
const RICE7: FactoryReadFn<E, CRF> = |reader| reader.read_rice(7);
const RICE8: FactoryReadFn<E, CRF> = |reader| reader.read_rice(8);
const RICE9: FactoryReadFn<E, CRF> = |reader| reader.read_rice(9);
const RICE10: FactoryReadFn<E, CRF> = |reader| reader.read_rice(10);
const PI1: FactoryReadFn<E, CRF> = |reader| reader.read_pi(1);
const PI2: FactoryReadFn<E, CRF> = |reader| reader.read_pi2();
const PI3: FactoryReadFn<E, CRF> = |reader| reader.read_pi(3);
const PI4: FactoryReadFn<E, CRF> = |reader| reader.read_pi(4);
const PI5: FactoryReadFn<E, CRF> = |reader| reader.read_pi(5);
const PI6: FactoryReadFn<E, CRF> = |reader| reader.read_pi(6);
const PI7: FactoryReadFn<E, CRF> = |reader| reader.read_pi(7);
const PI8: FactoryReadFn<E, CRF> = |reader| reader.read_pi(8);
const PI9: FactoryReadFn<E, CRF> = |reader| reader.read_pi(9);
const PI10: FactoryReadFn<E, CRF> = |reader| reader.read_pi(10);
const GOLOMB3: FactoryReadFn<E, CRF> = |reader| reader.read_golomb(3);
const GOLOMB5: FactoryReadFn<E, CRF> = |reader| reader.read_golomb(5);
const GOLOMB6: FactoryReadFn<E, CRF> = |reader| reader.read_golomb(6);
const GOLOMB7: FactoryReadFn<E, CRF> = |reader| reader.read_golomb(7);
const GOLOMB9: FactoryReadFn<E, CRF> = |reader| reader.read_golomb(9);
const GOLOMB10: FactoryReadFn<E, CRF> = |reader| reader.read_golomb(10);
const EXP_GOLOMB1: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(1);
const EXP_GOLOMB2: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(2);
const EXP_GOLOMB3: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(3);
const EXP_GOLOMB4: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(4);
const EXP_GOLOMB5: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(5);
const EXP_GOLOMB6: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(6);
const EXP_GOLOMB7: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(7);
const EXP_GOLOMB8: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(8);
const EXP_GOLOMB9: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(9);
const EXP_GOLOMB10: FactoryReadFn<E, CRF> = |reader| reader.read_exp_golomb(10);
pub const fn new(code: Codes) -> Result<Self, DispatchError> {
let code = code.canonicalize();
let read_func = match code {
Codes::Unary => Self::UNARY,
Codes::Gamma => Self::GAMMA,
Codes::Delta => Self::DELTA,
Codes::Omega => Self::OMEGA,
Codes::VByteBe => Self::VBYTE_BE,
Codes::VByteLe => Self::VBYTE_LE,
Codes::Zeta(2) => Self::ZETA2,
Codes::Zeta(3) => Self::ZETA3,
Codes::Zeta(4) => Self::ZETA4,
Codes::Zeta(5) => Self::ZETA5,
Codes::Zeta(6) => Self::ZETA6,
Codes::Zeta(7) => Self::ZETA7,
Codes::Zeta(8) => Self::ZETA8,
Codes::Zeta(9) => Self::ZETA9,
Codes::Zeta(10) => Self::ZETA10,
Codes::Rice(1) => Self::RICE1,
Codes::Rice(2) => Self::RICE2,
Codes::Rice(3) => Self::RICE3,
Codes::Rice(4) => Self::RICE4,
Codes::Rice(5) => Self::RICE5,
Codes::Rice(6) => Self::RICE6,
Codes::Rice(7) => Self::RICE7,
Codes::Rice(8) => Self::RICE8,
Codes::Rice(9) => Self::RICE9,
Codes::Rice(10) => Self::RICE10,
Codes::Pi(1) => Self::PI1,
Codes::Pi(2) => Self::PI2,
Codes::Pi(3) => Self::PI3,
Codes::Pi(4) => Self::PI4,
Codes::Pi(5) => Self::PI5,
Codes::Pi(6) => Self::PI6,
Codes::Pi(7) => Self::PI7,
Codes::Pi(8) => Self::PI8,
Codes::Pi(9) => Self::PI9,
Codes::Pi(10) => Self::PI10,
Codes::Golomb(3) => Self::GOLOMB3,
Codes::Golomb(5) => Self::GOLOMB5,
Codes::Golomb(6) => Self::GOLOMB6,
Codes::Golomb(7) => Self::GOLOMB7,
Codes::Golomb(9) => Self::GOLOMB9,
Codes::Golomb(10) => Self::GOLOMB10,
Codes::ExpGolomb(1) => Self::EXP_GOLOMB1,
Codes::ExpGolomb(2) => Self::EXP_GOLOMB2,
Codes::ExpGolomb(3) => Self::EXP_GOLOMB3,
Codes::ExpGolomb(4) => Self::EXP_GOLOMB4,
Codes::ExpGolomb(5) => Self::EXP_GOLOMB5,
Codes::ExpGolomb(6) => Self::EXP_GOLOMB6,
Codes::ExpGolomb(7) => Self::EXP_GOLOMB7,
Codes::ExpGolomb(8) => Self::EXP_GOLOMB8,
Codes::ExpGolomb(9) => Self::EXP_GOLOMB9,
Codes::ExpGolomb(10) => Self::EXP_GOLOMB10,
_ => return Err(DispatchError::UnsupportedCode(code)),
};
Ok(Self(read_func))
}
#[must_use]
#[inline(always)]
pub const fn new_with_func(read_func: FactoryReadFn<E, CRF>) -> Self {
Self(read_func)
}
#[must_use]
#[inline(always)]
pub const fn get_func(&self) -> FactoryReadFn<E, CRF> {
self.0
}
#[must_use]
#[inline(always)]
pub const fn get<'a>(
&self,
) -> super::FuncCodeReader<E, <CRF as CodesReaderFactory<E>>::CodesReader<'a>> {
super::FuncCodeReader::new_with_func(self.0)
}
}