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}