Search code examples
rustrust-macros

Treating idents as string in Rust macros


I have a configuration struct with some top level properties which I would like to put in sections. I order to provide deprecation warnings I made the following macro

macro_rules! deprecated {
($config:expr, $old:ident, $section:ident, $new:ident) => {
    if $config.$old.is_some() {
        println!(
            "$old configuration option is deprecated. Rename it to $new and put it under the section [$section]",
        );

        &$config.$old
    } else {
        if let Some(section) = &$config.$section {
            &section.$new
        } else {
            &None
        }
    }
};

}

This doesn't seem to work as expected as the macro parameters aren't substituted inside a string. How can I change the macro to achieve the desired effect?


Solution

  • The stringify! macro can turn an element into a string literal, and the concat! macro can concatenate several literals into a single string literal:

    println!(
        concat!(
            stringify!($old),
            " configuration option is deprecated. Rename it to ",
            stringify!($new),
            " and put it under the section [",
            stringify!($section),
            "]",
        )
    );
    

    Permalink to the playground