2

I have a function defined for i64 that returns an iterator over the number's digits.

(Playground)

fn digits_of(num: i64) -> impl Iterator<Item = u8> {
    let num = num.abs();
    let nth_digit = move |exp| (num / 10_i64.pow(exp) % 10) as u8;
    let largest_exponent = (num as f64).log10() as u32;
    (0..=largest_exponent).into_iter().map(nth_digit).rev()
}

fn main() {
    for digit in digits_of(-8675309) {
        println!("{}", digit);
    }
}

I would like to somehow generalize this for all of the primitive integer types, but I cannot think of a good way to do this.

One solution would be to manually implement the function for every primitive, which would work, but would be a lot of copy-and-pasting.

Another (undesirable) solution would be to implement it only twice for i128 and u128, where I could always cast a smaller type and invoke it the following way:

fn main() {
    let x: u8 = 10;
    for digit in digits_of(x as u128) {
        println!("{}", digit);
    }
}

I have tried to implement it using generics, where T: Integer + Div + Rem etc., but I can't cast the generic like I can with a primitive: num as f64

My inclination is that this may be possible with macro_rules! (perhaps using expr and ty), but I am quite new to macros in Rust. Any guidance would be appreciated.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ObliqueMotion
  • 483
  • 1
  • 5
  • 11

0 Answers0