Arseny Staroverov
Arseny Staroverov

Reputation: 168

How to split an ident into letters in Rust macro?

I need to write an multiply macro which converts ident into single letter idents and multiply them.

let a = 4;
let b = 7;
println!("{}", multiply!(abbabbb));
// println!("{}", (a * b * b * a * b * b * b))

but I dont know how to match a single letter.

I want to do something like this:

macro_rules! multiply {
    ($id:letter$other:tt) => {
        $id * multiply!($other)
    };
    ($id:ident) => {
        $id
    }
}

Upvotes: 3

Views: 847

Answers (2)

Jmb
Jmb

Reputation: 23434

You can't do it in a macro_rules macro. The closest you can do is to add spaces between the idents:

macro_rules! multiply {
    ($($id:ident)*) => {
       1 $(* $id)*
    }
}

fn main() {
    let a = 4;
    let b = 7;
    println!("{}", multiply!(a b b a b b b));
}

Playground

Upvotes: 2

totikom
totikom

Reputation: 306

You can't do it in pattern-matching macros (as in your example), only in procedural macros.

Even in procedural macros solving your problem will be quite hacky. In Rust an indent is a single indivisible element of AST, so to convert one indent to many you'll first have to convert it to String, divide it into characters and convert the characters back to indents.

Upvotes: 3

Related Questions