#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
mod code;
mod errors;
mod huffman;
mod table;
mod tree;
pub use crate::code::HfmnCode;
pub use errors::Error;
pub use huffman::CodeBook;
#[must_use]
pub fn chain(symbols: &[&HfmnCode]) -> (Vec<u8>, usize) {
let mut bytes = Vec::new();
let mut current_byte = 0_u8;
let mut bit_index = 0_usize;
for symbol in symbols {
for bit in symbol.bits() {
current_byte |= (bit as u8) << bit_index;
bit_index = bit_index.saturating_add(1);
if bit_index == 8 {
bytes.push(current_byte.reverse_bits());
current_byte = 0;
bit_index = 0;
}
}
}
if bit_index != 0 {
bytes.push(current_byte.reverse_bits());
}
(bytes, symbols.len())
}
#[cfg(test)]
mod tests {
use itertools::Itertools;
use super::*;
#[test]
fn chaining() {
let symbols = [
HfmnCode::from(0b0000_1111, 8),
HfmnCode::from(0b01011, 5),
HfmnCode::from(0b110, 3),
];
let (bytes, _) = chain(&symbols.iter().collect_vec());
let expected = vec![0b0000_1111, 0b0101_1110];
assert_eq!(bytes, expected);
}
}