use std::mem::size_of;
pub struct BitQueue
{
inner : u8,
bit_count: usize
}
impl BitQueue
{
pub fn new() -> BitQueue
{
BitQueue
{
inner : 0,
bit_count : 0
}
}
pub fn push(&mut self, byte : u8)
{
assert_eq!(self.inner, 0);
self.inner = byte;
self.bit_count += 8;
}
pub fn pop(&mut self, count : usize) -> u8
{
let mut result = self.inner.clone();
let trailing_0s = self.bit_count - count;
result = result >> trailing_0s;
if self.bit_count > 1
{
self.inner = self.inner << count + (size_of::<u8>() * 8 - self.bit_count);
self.inner = self.inner >> count + (size_of::<u8>() * 8 - self.bit_count);
}
else
{
self.inner = 0;
}
self.bit_count -= count;
return result as u8;
}
pub fn is_empty(&self) -> bool
{
self.bit_count == 0
}
pub fn len(&self) -> usize
{
self.bit_count
}
}
#[cfg(test)]
mod tests
{
use super::*;
#[test]
fn basic_pop()
{
let mut queue = BitQueue::new();
queue.push(0b11001110);
assert_eq!(0b1100, queue.pop(4));
assert_eq!(0b1110, queue.inner, "{:#b} != {:#b}",0b1110, queue.inner,);
}
#[test]
fn advanced_pop()
{
let mut queue = BitQueue::new();
queue.push(0b00010000);
assert_eq!(0b0001, queue.pop(4));
assert_eq!(0b0, queue.pop(1));
assert_eq!(0b00, queue.pop(2));
assert_eq!(0b0, queue.pop(1));
}
}