Skip to main content

chess/formats/
bits.rs

1// TODO: Use `winnow` machinery?
2// Note their note on not keeping "spare bits"
3// when converting back to byte parsers
4/// Bits from bytes
5#[derive(Debug)]
6pub struct Bits<'a> {
7    /// TODO: make this &mut and actually consume the bits/bytes
8    bytes: &'a [u8],
9    bit: u8,
10}
11
12impl<'a> From<&'a [u8]> for Bits<'a> {
13    fn from(bytes: &'a [u8]) -> Self {
14        Self { bytes, bit: 0 }
15    }
16}
17
18impl Iterator for Bits<'_> {
19    type Item = bool;
20
21    fn next(&mut self) -> Option<bool> {
22        if self.bytes.is_empty() {
23            return None;
24        }
25
26        if self.bit == 8 {
27            self.bytes = &self.bytes[1..];
28            if self.bytes.is_empty() {
29                return None;
30            }
31            self.bit = 0;
32        }
33
34        let set = self.bytes[0] & (0x80 >> self.bit) != 0;
35        self.bit += 1;
36        Some(set)
37    }
38
39    fn size_hint(&self) -> (usize, Option<usize>) {
40        let len = Bits::len(self);
41        (len, Some(len))
42    }
43}
44
45impl ExactSizeIterator for Bits<'_> {}
46
47impl<'a> Bits<'a> {
48    /// Turn bytes into bits
49    pub fn new(bytes: &'a [u8]) -> Self {
50        bytes.into()
51    }
52
53    pub fn is_empty(&self) -> bool {
54        self.len() == 0
55    }
56
57    /// Remaining number of bits
58    pub fn len(&self) -> usize {
59        (8 - self.bit as usize) + 8 * self.bytes.len()
60    }
61
62    /// Skip over `n` bits
63    pub fn skip(mut self, n: usize) -> Self {
64        for _ in 0..n {
65            self.next().unwrap();
66        }
67        self
68    }
69
70    /// Take `n` bits, interpreted as big-endian unsigned integer
71    pub fn unsigned(&mut self, n: usize) -> Option<usize> {
72        let mut unsigned = 0;
73
74        for _ in 0..n {
75            unsigned *= 2;
76            unsigned += self.next()? as usize;
77        }
78
79        Some(unsigned)
80    }
81}
82
83#[test]
84fn bits() {
85    let bits: &[u8] = &[];
86    let bits = Bits::from(bits);
87    assert!(bits.collect::<Vec<bool>>().is_empty());
88    let bits = Bits::from([0b1000_1111u8].as_slice());
89    assert_eq!(
90        vec![true, false, false, false, true, true, true, true],
91        bits.collect::<Vec<bool>>()
92    );
93}