Macro branch_on_format_capture

Source
branch_on_format_capture!() { /* proc-macro */ }
Expand description

Accepts two macro specifications and a set of format_args! arguments and conditionally expands based on whether the format_args! specifies any arguments to format.

Translating into macro_rules!, the syntax is roughly:

$capturing_macro:path $({$($capturing_prefix:tt)*})?,
$constant_macro:path $({$($constant_prefix:tt)*})?,
$format_string:literal
$($remaining_tokens:tt)*

This is a higher-order macro that accepts paths to other macros as input. A macro specification is the path to a macro excluding the final !, optionally followed by a {} containing prefix tokens.

If the format string would cause format_args! to capture arguments, the first path is invoked as a macro, with the arguments to that macro being the prefix tokens for that path followed by the format string and remaining tokens. Otherwise, the second macro path is used and invoked.

ยงExample

This is an optimizing format! macro that uses String::from instead of format! if there are no arguments other than the format string.

#[macro_export]
macro_rules! opt_format {
    () => {
        (alloc::string::String::new(), true)
    };
    (@capture $($args:tt)*) => {
        (format!($($args)*), false)
    };
    (@nocapture $str:literal) => {
        (alloc::string::String::from($str), true)
    };
    ($msg:tt $(,)?) => {
        format_args_conditional::branch_on_format_capture!(
            $crate::opt_format {@capture},
            $crate::opt_format {@nocapture},
            $msg
        )
    };
    ($($args:tt)*) => {
        opt_format!(@capture $($args)*)
    };
}