digits_iter/
lib.rs

1pub trait Digits: Sized {
2    fn digits(self, base: Self) -> DigitsIter<Self>;
3}
4
5pub struct DigitsIter<I> {
6    x: I,
7    base: I,
8}
9
10impl<I> DigitsIter<I> {
11    pub fn new(x: I, base: I) -> Self { Self { x, base } }
12}
13
14macro_rules! impl_uint {
15    ( $($ty:ty)* ) => { $(
16        impl Digits for $ty {
17            fn digits(self, base: Self) -> DigitsIter<Self> {
18                DigitsIter::new(self, base)
19            }
20        }
21        impl Iterator for DigitsIter<$ty> {
22            type Item = $ty;
23            fn next(&mut self) -> Option<$ty> {
24                if self.x == 0 {
25                    return None;
26                }
27
28                let res = self.x % self.base;
29                self.x /= self.base;
30                Some(res)
31            }
32        }
33    )* }
34}
35
36impl_uint! { u8 u16 u32 u64 u128 usize }
37
38#[test]
39fn sanity_check() {
40    assert_eq!(1234_u32.digits(10).collect::<Vec<_>>(), [4, 3, 2, 1]);
41    assert_eq!(0o123_u32.digits(8).collect::<Vec<_>>(), [3, 2, 1]);
42    assert_eq!(0x3e0f_u32.digits(16).collect::<Vec<_>>(), [15, 0, 14, 3]);
43    assert_eq!(0_u32.digits(10).next(), None);
44}