rust

Use `write!` without bringing the Write trait into scope in Rust


In my code generator, I need to generate this code without bringing std::fmt::Write trait into the scope:

    let mut s = String::new();
    let _ = write!(s, "Hello, world!");

I know it is possible to use fully qualified syntax for functions, but I am not sure if macros allow that?


Solution

  • The write macro is extremely simple and doesn't contain any special features:

    macro_rules! write {
        ($dst:expr, $($arg:tt)*) => {
            $dst.write_fmt($crate::format_args!($($arg)*))
        };
    }
    

    This means your code expands to this:

    let mut s = String::new();
    use std::fmt::Write;
    let _ = write!(s, "Hello, world!");
    
    // becomes
    
    let mut s = String::new();
    use std::fmt::Write;
    let _ = s.write_fmt(format_args!("Hello, world!"));
    

    And you can then replace this with associated function syntax:

    let mut s = String::new();
    let _ = std::fmt::Write::write_fmt(&mut s, format_args!("Hello, world!"));
    

    If the type of S isn't inferred, you can use fully qualified syntax:

    let _ = <String as std::fmt::Write>::write_fmt(&mut s, format_args!("Hello, world!"));
    

    Note that the write macro works with either std::fmt::Write or std::io::Write (or any write_fmt method in scope for the given type). You need to decide which one to use just as you would when using the macro.

    Also remember you can put use items alongside expressions, so you probably don't need to do any of the above:

    let _ = {
        use std::fmt::Write;
        write!(s, "Hello, world!")
    };