Search code examples
rustrust-macros

Is there a way to pass named arguments to format macros without repeating the variable names?


With new versions of Rust, you can simplify structure initialization like this:

Foo {
    a: a,
    b: b,
}

to this

Foo { a, b }

Is it possible to do something similar for format!/println!-like macros?

For now I need to write it like this:

let a = "a";
let b = "b";
write!(file, "{a} is {b}", a = a, b = b).unwrap();

Is it possible to write my own macros with an API like this:

let a = "a";
let b = "b";
my_write!(file, "{a} is {b}", a, b).unwrap();

Solution

  • RFC 2795 has been accepted and implemented. Starting in Rust 1.58, you will be able to go beyond your desired syntax:

    write!(file, "{a} is {b}").unwrap();
    

    Before then, you can write your own wrapper around println! and friends:

    macro_rules! myprintln {
        ($fmt:expr, $($name:ident),*) => { println!($fmt, $($name = $name),*) }
    }
    
    fn main() {
        let a = "alpha";
        let b = "beta";
        myprintln!("{a} is {b}", a, b);
    }
    

    This will likely always be limited compared to the full formatter macro, but it may be sufficient for your case.