hextree/
digits.rs

1use crate::Cell;
2
3pub(crate) struct Digits {
4    digits: u64,
5    remaining: u8,
6}
7
8impl Digits {
9    #[inline]
10    pub(crate) fn new(cell: Cell) -> Self {
11        let res = cell.res();
12        let mask = u128::MAX.wrapping_shl(64 - (3 * res as u32)) as u64;
13        let digits: u64 = cell.0.wrapping_shl(19) & mask;
14        Self {
15            digits,
16            remaining: res,
17        }
18    }
19}
20
21impl Iterator for Digits {
22    type Item = u8;
23
24    #[inline]
25    fn next(&mut self) -> Option<Self::Item> {
26        if self.remaining == 0 {
27            None
28        } else {
29            let out = (self.digits & (0b111 << 61)) >> 61;
30            self.digits <<= 3;
31            debug_assert!(out < 7);
32            self.remaining -= 1;
33            Some(out as u8)
34        }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_digits() {
44        let test_cases: &[(u64, &[u8])] = &[
45            (577164439745200127, &[]),                    // res 0
46            (585793956755800063, &[2, 0]),                // res 2
47            (592638622797135871, &[6, 3, 2]),             // res 3
48            (596251300178427903, &[3, 6, 6, 2]),          // res 4
49            (599803672997658623, &[3, 4, 4, 1, 4]),       // res 5
50            (604614882611953663, &[1, 4, 0, 4, 1, 0]),    // res 6
51            (608557861265473535, &[2, 0, 2, 3, 2, 1, 1]), // res 7
52        ];
53        for (index, ref_digits) in test_cases {
54            let idx = Cell::from_raw(*index).unwrap();
55            let digits = Digits::new(idx).collect::<Vec<u8>>();
56            assert_eq!(&&digits, ref_digits);
57        }
58    }
59}