Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Macros and format strings

Format strings

The std format macros take inline expressions. {expr} and {expr:spec} become positional arguments. A string inside a placeholder uses the literal’s escapes, as in "{tags.join(\", \")}"; in a raw literal its quotes are plain, as in r#"{v.join("-")}"#.

pub fn report(name: &str, values: &[i32], tags: &[&str]):
    println!("{name} has {values.len()} values")
    println!("{tags.join(\", \")}")
    assert!(!values.is_empty(), "{values.len():>4}")

becomes

#![allow(unused)]
fn main() {
pub fn report(name: &str, values: &[i32], tags: &[&str]) {
    println!("{} has {} values", name, values.len());
    println!("{}", tags.join(", "));
    assert!(!values.is_empty(), "{:>4}", values.len());
}
}

A string whose placeholders are all plain identifiers, positions, or {} is left as Rust. When a string with an inline expression has no explicit arguments, its plain identifiers become arguments too, so the arguments keep the string’s order.

This covers format!, print!, println!, eprint!, eprintln!, write!, writeln!, panic!, format_args!, todo!, unreachable!, and unimplemented!. The arguments of these macros, assert!, assert_eq!, assert_ne!, their debug_ forms, dbg!, vec!, and matches! are Renk expressions: vec![Foo.new(); 3] is vec![Foo::new(); 3].

Other macros, such as log::info!, are opaque Rust tokens, as are the payloads of #[...] and #![...] attributes.

view!

In a view! body, such as Leptos’s, each { block that spans several lines holds Renk statements, so they need no ;. Tags, attributes, and one-line blocks such as {count} stay Rust tokens.

view! {
    <button on:click=move |_| {
        set_count.update(|n| *n += 1)
        log::info!("clicked")
    }>
        {count}
    </button>
}

becomes

#![allow(unused)]
fn main() {
view! {
    <button on:click=move |_| {
        set_count.update(|n| *n += 1);
        log::info!("clicked")
    }>
        {count}
    </button>
}
}

macro_rules!

Arms are indentation-based. Patterns and bodies are Rust tokens, kept as written.

macro_rules! make_message:
    ($name:expr) => format!("hello {}", $name)
    ($name:expr, $greeting:expr) =>:
        format!("{} {}", $greeting, $name)

A multi-line pattern =>: arm keeps every indented body line.