macro_rules! compile_args {
    (capacity: $cap:expr, $($arg:expr $(=> $fmt:expr)?),+) => { ... };
    ($($arg:expr $(=> $fmt:expr)?),+) => { ... };
}
Expand description

Concatenates arguments in compile time.

Specifying arguments

Arguments to this macro must be comma-separated. The argument type must be supported; for now, the supported types are:

  • Signed and unsigned integers (u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize)
  • Strings (&str)
  • Ascii strings
  • Chars (char)
  • References to CompileArgs.

Due to how Rust type inference works, you might need to specify the type suffix for integer literals (e.g., 42_usize instead of 42).

Optionally, an argument may specify its format as $arg => $fmt. A format is mandatory if the argument is not a constant; e.g. if it is an argument or a local variable in a const fn.

The value output by the macro is CompileArgs.

Specifying capacity

You can specify capacity of the returned CompileArgs by prefacing arguments with capacity: $cap,. Here, $cap is a constant expression of type usize. The specified capacity must be greater or equal that the capacity inferred from the arguments; the macro will fail with a compilation error otherwise.

See also

  • compile_panic! provides a version of the panic! macro with support of dynamic arguments.
  • compile_assert! provides a version of the assert! macro with support of dynamic arguments.

Examples

Basic usage

const ARGS: CompileArgs<9> = compile_args!(2_u32, " + ", 2_u32, " = ", 2_u32 + 2);
assert_eq!(ARGS.as_str(), "2 + 2 = 4");

Usage in const fn with dynamic args

use compile_fmt::{compile_args, fmt};
use std::fmt;

const fn create_args(x: usize) -> impl fmt::Display {
    let args = compile_args!(
        "2 * x + 3 = ", 2 * x + 3 => fmt::<usize>()
    );
    // ^ `args` are evaluated in compile time, but are not a constant.
    // They can still be useful e.g. for creating compile-time panic messages.
    assert!(x < 1000, "{}", args.as_str());
    args
}

let args = create_args(100);
assert_eq!(args.to_string(), "2 * x + 3 = 203");

Usage with explicit capacity

let args = compile_args!(capacity: 16, "Value: ", 42_i32);
assert_eq!(args.as_str(), "Value: 42");

Insufficient specified capacity will lead to a compilation error:

let args = compile_args!(capacity: 4, "Value: ", 42_i32);

The error message will include details about the necessary capacity:

error[E0080]: evaluation of constant value failed
   -->
    |
    |     let args = compile_args!(capacity: 4, "Value: ", 42_i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the evaluated program panicked at 'Insufficient capacity (4 bytes)
provided for `compile_args` macro; it requires at least 9 bytes'