#![cfg_attr(
all(not(test), not(feature = "entropy")),
expect(
dead_code,
reason = "without the `entropy` codecs only the Huffman table construction is used (by pivco-huffman)"
)
)]
pub(crate) mod bits;
pub(crate) mod fse;
pub(crate) mod huf;
pub(crate) mod huf16;
use thiserror::Error;
pub(crate) const HISTOGRAM_PID: i32 = 246;
pub(crate) const HUF_CTABLE_PID: i32 = 247;
#[derive(Error, Debug, Clone, Copy, Eq, PartialEq)]
pub(crate) enum EntropyError {
#[error("entropy coding failed")]
Generic,
#[error("table log too large")]
TableLogTooLarge,
#[error("symbol value too large")]
MaxSymbolValueTooLarge,
#[error("destination too small")]
DstSizeTooSmall,
}
impl EntropyError {
pub(crate) const fn code(self) -> usize {
match self {
Self::Generic => 1,
Self::TableLogTooLarge => 44,
Self::MaxSymbolValueTooLarge => 46,
Self::DstSizeTooSmall => 70,
}
}
}
pub(crate) const fn highbit32(value: u32) -> u32 {
31 - (value | 1).leading_zeros()
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
#[test]
fn error_codes_follow_zstd_numbering() {
assert_eq!(EntropyError::Generic.code(), 1);
assert_eq!(EntropyError::TableLogTooLarge.code(), 44);
assert_eq!(EntropyError::MaxSymbolValueTooLarge.code(), 46);
assert_eq!(EntropyError::DstSizeTooSmall.code(), 70);
assert_eq!(EntropyError::Generic.to_string(), "entropy coding failed");
assert_eq!(
EntropyError::TableLogTooLarge.to_string(),
"table log too large"
);
assert_eq!(
EntropyError::MaxSymbolValueTooLarge.to_string(),
"symbol value too large"
);
assert_eq!(
EntropyError::DstSizeTooSmall.to_string(),
"destination too small"
);
}
#[test]
fn highbit32_is_the_floor_of_log2() {
assert_eq!(highbit32(1), 0);
assert_eq!(highbit32(2), 1);
assert_eq!(highbit32(255), 7);
assert_eq!(highbit32(256), 8);
assert_eq!(highbit32(u32::MAX), 31);
assert_eq!(highbit32(0), 0);
}
}