const U8BITS: usize = 8;
pub struct BitIterator<'a> {
object: &'a [u8],
next_index: usize,
end_index: usize,
}
impl<'a> BitIterator<'a> {
pub fn from_bytes(obj: &'a [u8]) -> BitIterator<'_> {
BitIterator {
object: obj,
next_index: 0,
end_index: obj.len() * U8BITS,
}
}
pub fn count_ones(&self) -> u32 {
self.object.iter().fold(0, |acc, bv| acc + bv.count_ones())
}
}
impl<'a> Iterator for BitIterator<'a> {
type Item = bool;
fn next(&mut self) -> Option<bool> {
if self.next_index != self.end_index {
let (byte_index, bit_index) = (self.next_index / U8BITS, self.next_index % U8BITS);
let bit = self.object[byte_index] >> bit_index & 0x1;
self.next_index += 1;
Some(bit == 0x1)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.end_index, Some(self.end_index))
}
}
impl<'a> ExactSizeIterator for BitIterator<'a> {}
#[test]
fn test_iterator() {
let bytes = vec![0xCA, 0xFE];
let expected_bits = vec![0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1];
for (i, bit) in BitIterator::from_bytes(&bytes).enumerate() {
println!("{} == {}", bit, expected_bits[i] == 1);
assert_eq!(bit, expected_bits[i] == 1);
}
}