Extract objects in an expression in a macro in Rust

41 Views Asked by At

I have tried to pass my local objects in a macro call with a spesific pattern and failed. For example:

macro_rules! run_map {
    (($vector: expr).map(($closure: expr))) => {
        $vector().iter().map($closure: expr).collect::<Vec<_>>()
    };
}

fn main() {
    let my_vector: Vec<i32> = vec![3,4,5];
    run_map!(my_vector.map(|e| e * e));
}

Here is the error i get:

run_map!(my_vector.map(|e| e * e));
         ^^^^^^^^^ no rules expected this token in macro call

How can i extract objects and use them separately in an expression in a macro?

1

There are 1 best solutions below

0
mousetail On BEST ANSWER

Expressions in macros must be delimited in some way.

macro_rules! run_map {
    (($vector: expr).map($closure: expr)) => {
        // remove the () after $vector and the :expr after $closure here
        $vector.iter().map($closure).collect::<Vec<_>>()
    };
}

fn main() {
    let my_vector: Vec<i32> = vec![3,4,5];
    // add () around my_vector and the closure here
    let out = run_map!((my_vector).map(|e| e * e));
    println!("{out:?}");
}

See demo in the rust playground

The macro needs to be able to determine which part of the expression you want and which you don't. So it must be surrounded by something not valid in an expression like {}, () or []. Even something like:

($vector: expr;.map(($closure: expr))) => {

Works because a ; is a valid delimiter for expressions