pub trait Bits: Iterator<Item = bool> + Clone + std::fmt::Debug {
fn len(&self) -> usize;
fn take_as_u32(&mut self, n: usize) -> u32 {
assert!(n <= 32);
assert!(n <= self.len());
let mut ret = 0;
for _ in 0..n {
ret <<= 1;
let bit = self
.next()
.expect(&format!("Ran out of bits! n={}, bits={:?} ", n, self));
if bit {
ret |= 1;
}
}
ret
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::vecboolbits::VecBoolBits;
fn bits(s: &str) -> VecBoolBits {
VecBoolBits::new(
s.chars()
.map(|c| if c == '1' { true } else { false })
.collect(),
)
}
fn stringify<B: Bits>(bits: B) -> String {
let mut ret = String::new();
for bit in bits {
ret.push(if bit { '1' } else { '0' });
}
ret
}
#[test]
fn taking_whole_thing_as_u32_clears_bits() {
let mut b = bits("1000001");
let taken = b.take_as_u32(7);
assert_eq!(taken, 0b01000001);
assert_eq!(b.len(), 0);
}
#[test]
fn taking_some_bits_leaves_the_rest() {
let mut b = bits(
"\
1000\
00000000\
11111111\
",
);
let taken = b.take_as_u32(12);
assert_eq!(taken, 0b0000100000000000);
assert_eq!(stringify(b), "11111111");
}
}