i-dunno 0.6.0

RFC 8771 Internationalized Deliberately Unreadable Network Notation
Documentation
pub trait Bits: Iterator<Item = bool> + Clone + std::fmt::Debug {
    fn len(&self) -> usize;

    /// Take n bits from the supplied Bits, and return those bits
    /// interpreted as a u32.
    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");
    }
}