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 let a: Vec<_> = 1234_u32.digits(10).collect();
41 assert_eq!(a, [4, 3, 2, 1]);
42
43 let a: Vec<_> = 0_u32.digits(10).collect();
44 assert!(a.is_empty());
45
46 let a: Vec<_> = 13_u32.digits(2).collect();
47 assert_eq!(a, [1, 0, 1, 1]);
48}