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}