use crate::bits::Bits;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BytesBits {
bytes: Vec<u8>,
idx: usize,
}
impl BytesBits {
pub fn new(bytes: Vec<u8>) -> Self {
Self { bytes, idx: 0 }
}
}
impl Iterator for BytesBits {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
let byte_num: usize = self.idx / 8;
let bit_num: usize = self.idx % 8;
self.idx += 1;
self.bytes
.get(byte_num)
.map(|byte| (byte & (1 << (7 - bit_num))) != 0)
}
}
impl Bits for BytesBits {
fn len(&self) -> usize {
let bits = self.bytes.len() * 8;
if bits < self.idx {
0
} else {
bits - self.idx
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn stringify<B: Bits>(bits: B) -> String {
let mut ret = String::new();
for bit in bits {
ret.push(if bit { '1' } else { '0' });
}
ret
}
fn bits2str(bytes: &[u8]) -> String {
stringify(BytesBits::new(bytes.to_vec()))
}
#[test]
fn empty_list_of_bytes_is_no_bits() {
assert_eq!(bits2str(&[]), "");
}
#[test]
fn zero_bytes_is_zero_bits() {
assert_eq!(bits2str(&[0]), "00000000");
assert_eq!(bits2str(&[0, 0]), "0000000000000000");
}
#[test]
fn some_numbers_come_out_as_bits() {
assert_eq!(
bits2str(&[255, 128, 6, 0]),
"\
11111111\
10000000\
00000110\
00000000\
",
);
}
}