pub struct MoveToFrontDecoder {
symbols: [u8; 256],
}
impl MoveToFrontDecoder {
pub fn new() -> Self {
let mut this = Self::new_from_symbols([0u8; 256]);
for (i, symbol) in this.symbols.iter_mut().enumerate() {
*symbol = i as u8;
}
this
}
pub fn new_from_symbols(symbols: [u8; 256]) -> Self {
Self { symbols }
}
pub fn decode(&mut self, n: u8) -> u8 {
let b = self.symbols[usize::from(n)];
#[cfg(feature = "rustc_1_37")]
self.symbols.copy_within(..usize::from(n), 1);
#[cfg(not(feature = "rustc_1_37"))]
{
let symbols = self.symbols;
self.symbols[1..=usize::from(n)].copy_from_slice(&symbols[..usize::from(n)]);
}
self.symbols[0] = b;
b
}
pub fn first(&self) -> u8 {
self.symbols[0]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_stuff() {
let mut decoder = MoveToFrontDecoder::new();
for i in 0..=255 {
assert_eq!(i, usize::from(decoder.symbols[i]));
}
let decode = decoder.decode(0);
assert_eq!(decode, 0);
for i in 0..=255 {
assert_eq!(i, usize::from(decoder.symbols[i]));
}
let decode = decoder.decode(5);
assert_eq!(decode, 5);
assert_eq!(decoder.symbols[0], 5);
assert_eq!(decoder.symbols[1], 0);
assert_eq!(decoder.symbols[2], 1);
assert_eq!(decoder.symbols[3], 2);
assert_eq!(decoder.symbols[4], 3);
assert_eq!(decoder.symbols[5], 4);
for i in 6..=255 {
assert_eq!(i, usize::from(decoder.symbols[i]));
}
}
}