pub use compactly_derive::EncodeV2 as Encode;
mod ans;
mod arc;
mod arith;
mod array;
mod bit_context;
mod bits;
mod bools;
mod byte;
mod bytes;
mod floats;
#[cfg(feature = "generate_bit_context")]
pub mod generate_bit_context;
mod ints;
mod low_cardinality;
mod maps;
mod millibits;
mod option;
mod other_crate_types;
mod raw;
mod sets;
mod string;
mod tuples;
mod ulessthan;
mod usizes;
mod vecs;
use crate::{LowCardinality, Small};
pub use ans::Ans;
pub use arith::Range;
pub use millibits::Millibits;
pub use raw::Raw;
pub use ulessthan::ULessThan;
const FIFTY_PERCENT: ans::Probability = ans::Probability::new(127, 127);
pub trait EntropyCoder: Default {
fn encode_bit(&mut self, probability: ans::Probability, bit: bool);
fn encode<T: Encode>(value: &T) -> Self {
let mut writer = Self::default();
value.encode(&mut writer, &mut T::Context::default());
writer
}
fn encode_incompressible_bytes(&mut self, bytes: &[u8]) {
for mut b in bytes.iter().copied() {
for _ in 0..8 {
self.encode_bit(FIFTY_PERCENT, (b & 1) == 1);
b >>= 1;
}
}
}
}
pub trait EntropyDecoder {
fn decode_bit_nonadaptive(
&mut self,
probability: ans::Probability,
) -> Result<bool, std::io::Error>;
#[inline(always)]
fn decode_bit(
&mut self,
context: &mut bit_context::BitContext,
) -> Result<bool, std::io::Error> {
let bit = self.decode_bit_nonadaptive(context.probability())?;
*context = context.adapt(bit);
Ok(bit)
}
#[inline(always)]
fn decode_incompressible_bytes(&mut self, bytes: &mut [u8]) -> Result<(), std::io::Error> {
for v in bytes {
let mut b = 0;
for i in 0..8 {
b = b | ((self.decode_bit_nonadaptive(FIFTY_PERCENT)? as u8) << i);
}
*v = b;
}
Ok(())
}
}
pub trait Encode: Sized {
type Context: Default + Clone;
fn encode<E: EntropyCoder>(&self, encoder: &mut E, ctx: &mut Self::Context);
fn decode<D: EntropyDecoder>(
entropy_decoder: &mut D,
ctx: &mut Self::Context,
) -> Result<Self, std::io::Error>;
fn millibits(&self) -> Millibits {
let mut m = Millibits::default();
self.encode(&mut m, &mut Self::Context::default());
m
}
}
pub fn encode<T: Encode>(value: &T) -> Vec<u8> {
let mut writer = arith::Range::default();
value.encode(&mut writer, &mut T::Context::default());
writer.into_vec()
}
pub fn decode<T: Encode>(mut bytes: &[u8]) -> Option<T> {
let mut reader = arith::Decoder::new(&mut bytes);
T::decode(&mut reader, &mut T::Context::default()).ok()
}
pub trait EncodingStrategy<T> {
type Context: Default + Clone;
fn encode<E: EntropyCoder>(value: &T, writer: &mut E, ctx: &mut Self::Context);
fn decode<D: EntropyDecoder>(
reader: &mut D,
ctx: &mut Self::Context,
) -> Result<T, std::io::Error>;
}
pub fn encode_with<T: Encode, S: EncodingStrategy<T>>(_: S, value: &T) -> Vec<u8> {
let mut writer = Range::default();
S::encode(value, &mut writer, &mut S::Context::default());
writer.into_vec()
}
pub fn decode_with<T: Encode, S: EncodingStrategy<T>>(_: S, mut bytes: &[u8]) -> Option<T> {
let mut reader = arith::Decoder::new(&mut bytes);
S::decode(&mut reader, &mut S::Context::default()).ok()
}
impl<T, S: EncodingStrategy<T>> Encode for crate::Encoded<T, S> {
type Context = S::Context;
#[inline]
fn encode<E: EntropyCoder>(&self, writer: &mut E, ctx: &mut Self::Context) {
S::encode(&self.value, writer, ctx)
}
#[inline]
fn decode<D: EntropyDecoder>(
reader: &mut D,
ctx: &mut Self::Context,
) -> Result<Self, std::io::Error> {
Ok(Self {
value: S::decode(reader, ctx)?,
_phantom: std::marker::PhantomData,
})
}
}
impl<T: Encode> EncodingStrategy<T> for crate::Normal {
type Context = <T as Encode>::Context;
#[inline]
fn encode<E: EntropyCoder>(value: &T, writer: &mut E, ctx: &mut Self::Context) {
value.encode(writer, ctx)
}
fn decode<D: EntropyDecoder>(
reader: &mut D,
ctx: &mut Self::Context,
) -> Result<T, std::io::Error> {
T::decode(reader, ctx)
}
}
#[cfg(test)]
macro_rules! assert_size {
($v:expr, $size:expr) => {
let v = $v;
let bytes = super::encode(&v);
let decoded = super::decode(&bytes);
assert_eq!(decoded, Some(v), "decoded value is incorrect");
assert_eq!(bytes.len(), $size, "unexpected size");
};
}
#[cfg(test)]
pub(crate) use assert_size;
#[cfg(test)]
macro_rules! assert_bits {
($v:expr, $size:expr) => {
let ans = $v;
let bytes = super::encode(&ans);
println!("Bytes are {bytes:?} for {ans:?}");
let decoded = super::decode(&bytes);
assert_eq!(decoded, Some(ans), "decoded value is incorrect");
let v = (
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
);
let bytes = super::encode(&v);
let decoded = super::decode(&bytes);
assert_eq!(decoded, Some(v), "decoded tuple value is incorrect");
assert_eq!((bytes.len() + 4) / 8, $size, "unexpected number of bits");
};
($v:expr, $size:expr, $msg:expr) => {
let ans = $v;
let bytes = super::encode(&ans);
let decoded = super::decode(&bytes);
assert_eq!(decoded, Some(ans), "decoded value is incorrect: {}", $msg);
let v = (
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
);
let bytes = super::encode(&v);
let decoded = super::decode(&bytes);
assert_eq!(
decoded,
Some(v),
"decoded tuple value is incorrect: {}",
$msg
);
assert_eq!(
(bytes.len() + 4) / 8,
$size,
"unexpected number of bits: {}",
$msg
);
};
}
#[cfg(test)]
pub(crate) use assert_bits;
#[cfg(test)]
macro_rules! raw_bits {
($v:expr, $size:expr) => {
let v = $v;
let encoded = super::Raw::encode(&v);
let decoded = super::Raw::decode(&encoded);
let (bits, entropy) = super::Raw::sizes(&v);
assert_eq!(decoded, Some(v));
assert_eq!(bits, $size, "unexpected number of raw bits");
assert_eq!(entropy, super::Millibits::bits($size), "unexpected entropy");
};
($v:expr, $size:expr, $millibits:expr) => {
let (bits, entropy) = super::Raw::sizes(&$v);
assert_eq!(bits, $size, "unexpected number of raw bits");
assert_eq!(entropy, $millibits, "unexpected entropy");
};
}
#[cfg(test)]
pub(crate) use raw_bits;
#[cfg(test)]
macro_rules! assert_ans_bits {
($v:expr, $size:expr) => {
let ans = $v;
let bytes = super::Ans::encode(&ans);
let decoded = super::Ans::decode(&bytes);
assert_eq!(decoded, Some(ans), "decoded value is incorrect");
let v = (
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
);
let bytes = super::Ans::encode(&v);
let decoded = super::Ans::decode(&bytes);
assert_eq!(decoded, Some(v), "decoded tuple value is incorrect");
assert_eq!((bytes.len() + 4) / 8, $size, "unexpected number of bits");
};
($v:expr, $size:expr, $msg:expr) => {
let ans = $v;
let bytes = super::Ans::encode(&ans);
let decoded = super::Ans::decode(&bytes);
assert_eq!(decoded, Some(ans), "decoded value is incorrect: {}", $msg);
let v = (
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
($v, $v, $v, $v, $v, $v, $v, $v),
);
let bytes = super::Ans::encode(&v);
let decoded = super::Ans::decode(&bytes);
assert_eq!(
decoded,
Some(v),
"decoded tuple value is incorrect: {}",
$msg
);
assert_eq!(
(bytes.len() + 4) / 8,
$size,
"unexpected number of bits: {}",
$msg
);
};
}
#[cfg(test)]
pub(crate) use assert_ans_bits;