Macro utility/trick that provides repetition knowing index and number of repetitions of a repeating variable?

⚓ Rust    📅 2026-01-10    👤 surdeus    👁️ 2      

surdeus

Something I need to do:

macro_rules! assert_dyn_iterable_eq {
    ($iterable:expr, [$($type:ty | $value:expr),+ $(,)?]) => {
        {
            // Note: Would need to check for the case that $iterable has less/more than supplied elements,
            // but omitting here.
            for (i, x) in ($iterable).iter().enumerate() {
                // Error: variable `r#type` is still repeating at this depth
                let Some(x) = x.downcast_ref::<$type>()
                else {
                    return Err(format!(
                        "Item {} is not of type {}.", i + 1, stringify!($type)))
                };
                assert_eq!(x, &($value), "Item {} is not equal to expected value.", i + 1);
            }
        }
    };
}

Another approach:

macro_rules! assert_dyn_iterable_eq {
    ($iterable:expr, [$($type:ty | $value:expr),+ $(,)?]) => {
        {
            let mut i = 0;
            for x in $iterable {
                i += 1;
                if i > $NUMBER_OF_ELEMENTS {
                    return Err(format!("Iterable has more than {} elements.", $NUMBER_OF_ELEMENTS));
                }
                $(
                    if i == $THE_ELEMENT_INDEX {
                        let Some(x) = x.downcast_ref::<$type>()
                        else {
                            return Err(format!(
                                "Item {} is not of type {}.", i + 1, stringify!($type)))
                        };
                        assert_eq!(x, &($value), "Item {} is not equal to expected value.", i + 1);
                    }
                )+
            }
            if i < $NUMBER_OF_ELEMENTS {
                return Err(format!("Iterable has less than {} elements (has {i} elements).", $NUMBER_OF_ELEMENTS));
            }
        }
    };
}

What is the current best way to do this?

I know 3086-macro-metavar-expr - The Rust RFC Book, but it looks unfinished due to lack of developer time, so I'd avoid it if possible.

2 posts - 2 participants

Read full topic

🏷️ Rust_feed