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, &[]), (585793956755800063, &[2, 0]), (592638622797135871, &[6, 3, 2]), (596251300178427903, &[3, 6, 6, 2]), (599803672997658623, &[3, 4, 4, 1, 4]), (604614882611953663, &[1, 4, 0, 4, 1, 0]), (608557861265473535, &[2, 0, 2, 3, 2, 1, 1]), ];
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}