use super::roblox_bit_reader::{BitCounterError, RobloxBitReader};
#[derive(Debug, Eq, PartialEq)]
pub enum Symbol {
Continue, Split, Left, Right, End, }
pub struct SymbolReader<'a> {
bit_reader: RobloxBitReader<'a>,
}
impl<'a> SymbolReader<'a> {
pub fn new(bytes: &'a [u8], bits: u32) -> Result<Self, BitCounterError> {
let bit_reader = RobloxBitReader::new(bytes, bits)?;
Ok(Self { bit_reader })
}
pub const fn remaining_bits(&self) -> u32 {
self.bit_reader.remaining_bits()
}
pub fn read(&mut self) -> Result<Symbol, BitCounterError> {
if self.bit_reader.read(1)? == 0 {
return Ok(Symbol::Continue);
}
let bits = self.bit_reader.read(2)?;
Ok(match (bits & 0b10 != 0, bits & 0b01 != 0) {
(false, false) => Symbol::Split,
(false, true) => Symbol::Left,
(true, false) => Symbol::Right,
(true, true) => Symbol::End,
})
}
}
#[test]
fn read_symbols() {
#[rustfmt::skip]
const BYTES: [u8; 8] = [
0b0_101_111_0, 0b0_0_110_0_10, 0b0_101_111_0, 0b0_0_110_0_10, 0b0_101_111_0, 0b0_0_110_0_10, 0b0_101_111_0, 0b110_0_10, ];
let mut r = SymbolReader::new(&BYTES, 62).unwrap();
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Right));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Split));
assert_eq!(r.read(), Ok(Symbol::Left));
assert_eq!(r.read(), Ok(Symbol::End));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Right));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Split));
assert_eq!(r.read(), Ok(Symbol::Left));
assert_eq!(r.read(), Ok(Symbol::End));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Right));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Split));
assert_eq!(r.read(), Ok(Symbol::Left));
assert_eq!(r.read(), Ok(Symbol::End));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Right));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Ok(Symbol::Split));
assert_eq!(r.read(), Ok(Symbol::Left));
assert_eq!(r.read(), Ok(Symbol::End));
assert_eq!(r.read(), Ok(Symbol::Continue));
assert_eq!(r.read(), Err(BitCounterError::NotEnoughBits));
}
#[test]
fn empirical() {
const BYTES: [u8; 4] = [183, 219, 55, 0];
let mut r = SymbolReader::new(&BYTES, 22).unwrap();
assert_eq!(r.bit_reader.read(1), Ok(1));
assert_eq!(r.read(), Ok(Symbol::Left));
assert_eq!(r.read(), Ok(Symbol::End));
assert_eq!(r.read(), Ok(Symbol::Left));
assert_eq!(r.read(), Ok(Symbol::Left));
assert_eq!(r.read(), Ok(Symbol::Right));
assert_eq!(r.read(), Ok(Symbol::Right));
assert_eq!(r.read(), Ok(Symbol::End));
assert_eq!(r.read(), Err(BitCounterError::NotEnoughBits));
}