split_digits/
lib.rs

1pub struct SplitDigitIterator {
2    num: usize,
3    divisor: usize,
4}
5
6impl SplitDigitIterator {
7    pub fn new(num: usize) -> Self {
8        let mut divisor = 1;
9        while num >= divisor * 10 {
10            divisor *= 10;
11        }
12        Self { num, divisor }
13    }
14}
15
16impl Iterator for SplitDigitIterator {
17    type Item = u8;
18
19    fn next(&mut self) -> Option<Self::Item> {
20        if self.divisor == 0 {
21            None
22        } else {
23            let v: u8 = (self.num / self.divisor) as u8;
24            self.num %= self.divisor;
25            self.divisor /= 10;
26            Some(v)
27        }
28    }
29}
30
31impl DoubleEndedIterator for SplitDigitIterator {
32    fn next_back(&mut self) -> Option<Self::Item> {
33        if self.num != 0 {
34            let digit = (self.num % 10) as u8;
35            self.num /= 10;
36            Some(digit)
37        } else {
38            None
39        }
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use crate::SplitDigitIterator;
46
47    #[test]
48    fn test_split_digits() {
49        assert_eq!(
50            vec![1, 2, 3],
51            SplitDigitIterator::new(123).collect::<Vec<_>>()
52        );
53        assert_eq!(
54            vec![3, 2, 1],
55            SplitDigitIterator::new(321).collect::<Vec<_>>()
56        );
57        assert_eq!(vec![1], SplitDigitIterator::new(1).collect::<Vec<_>>());
58        assert_eq!(
59            vec![1, 0, 0, 1],
60            SplitDigitIterator::new(1001).collect::<Vec<_>>()
61        );
62    }
63
64    #[test]
65    fn test_split_digits_trailing_zeroes() {
66        assert_eq!(
67            vec![1, 2, 0, 0, 0],
68            SplitDigitIterator::new(12000).collect::<Vec<_>>()
69        );
70        assert_eq!(vec![1, 0], SplitDigitIterator::new(10).collect::<Vec<_>>());
71    }
72
73    #[test]
74    fn test_split_digits_reverse() {
75        let digits: Vec<u8> = SplitDigitIterator::new(568764567).rev().collect();
76        assert_eq!(digits, vec![7, 6, 5, 4, 6, 7, 8, 6, 5]);
77
78        let digits: Vec<u8> = SplitDigitIterator::new(1001).rev().collect();
79        assert_eq!(digits, vec![1, 0, 0, 1]);
80    }
81}