i-dunno 0.6.0

RFC 8771 Internationalized Deliberately Unreadable Network Notation
Documentation
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\
            ",
        );
    }
}