Macro const_panic::concat_panic

source ·
macro_rules! concat_panic {
    ($($args:tt)*) => { ... };
}
Expand description

Panics with the concanenation of the arguments.

Examples below

§Syntax

This macro uses this syntax:

concat_panic!(
    $($fmtarg:expr;)?
    $(
        $( $format_override:tt: )? $arg_to_fmt:expr
    ),*
    $(,)?
)

$fmtarg is an optional FmtArg argument which defaults to FmtArg::DEBUG, determining how non-literal $arg_to_fmt arguments are formatted.

$format_override overrides the $fmtarg argument, changing how that $arg_to_fmt argument is formatted.

§Formatting

Literals are Display formatted by default, so that you can pass string literals without worrying about what the current formatting settings are.

Expressions are formatted as determined by the $fmtarg argument.

Note that literals inside parentheses (eg: (100)) are considered expressions by this macro.

§Formatting overrides

You can override how an argument is formatted by prefixing the argument expression with any of the options below:

  • debug: or {?}:: Debug formats the argument.
  • alt_debug: or {#?}:: alternate-Debug formats the argument.
  • display: or {}:: Display formats the argument.
  • alt_display: or {#}:: alternate-Display formats the argument.
  • bin: or {b}:: Debug formats the argument, with binary-formatted numbers.
  • alt_bin: or {#b}:: alternate-Debug formats the argument, with binary-formatted numbers.
  • hex: or {X}:: Debug formats the argument, with hexadecimal-formatted numbers.
  • alt_hex: or {#X}:: alternate-Debug formats the argument, with hexadecimal-formatted numbers.

§String formatting

String expressions are debug-formatted like this:

  • Prepending and appending the double quote character (").
  • Escaping the '\t','\n','\r','\\', '\'', and'\"' characters.
  • Escaping control characters with \xYY, where YY is the hexadecimal value of the control character.

§Limitations

Arguments to the formatting/panicking macros must have a fully inferred concrete type, because const_panic macros use duck typing to call methods on those arguments.

One effect of that limitation is that you will have to pass suffixed integer literals (eg: 100u8) when those integers aren’t inferred to be a concrete type.

§Examples

§Odd-type

use const_panic::concat_panic;

use odd::Odd;

const _: Odd = match Odd::new(3 * 4) {
    Ok(x) => x,
    Err(x) => concat_panic!("\nexpected odd number, got `", x, "`"),
};

mod odd {
    pub struct Odd(u32);

    impl Odd {
        pub const fn new(n: u32) -> Result<Odd, Even> {
            if n % 2 == 1 {
                Ok(Odd(n))
            } else {
                Err(Even(n))
            }
        }
    }

    #[derive(const_panic::PanicFmt))]
    pub struct Even(u32);
}

produces this compile-time error:

error[E0080]: evaluation of constant value failed
  --> src/macros.rs:188:15
   |
10 |     Err(x) => concat_panic!("\nexpected odd number, got `", x, "`"),
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '
expected odd number, got `12`', src/macros.rs:10:15
   |
   = note: this error originates in the macro `concat_panic` (in Nightly builds, run with -Z macro-backtrace for more info)

§All the syntax

This example demonstrates using all of the syntax of this macro.

use const_panic::{FmtArg, concat_panic, fmt};

const _: () = concat_panic!{
    // the optional `$fmtarg` parameter.
    // If this argument isn't passed, it defaults to `FmtArg::DEBUG`
    FmtArg::ALT_DEBUG;

    "\n\nshowing off literals:\n",
    100u8,
    "hello",

    "\n\nnon-literals with formatting determined by the $fmtarg parameter:\n",
    // this is considered a non-literal, because it's inside other tokens.
    ("a non-literal"),
    [100u8, 200],

    "\n\nexplicitly debug formatted:\n",
    debug: "foo",
    // `{?}:` is The same as `debug:`
    {?}: "bar",

    "\n\nalternate debug formatted:\n",
    alt_debug: ["foo"],
    // `{#?}:` is The same as `alt_debug:`
    {#?}: "bar",

    "\n\ndisplay formatted:\n",
    display: "baz",
    // `{}:` is The same as `display:`
    {}: ["qux", "aaa"],

    "\n\nalternate display formatted:",
    alt_display: ["bbb", "ccc"],
    // `{#}:` is The same as `alt_display:`
    {#}: ["bbb", "ccc"],

    "\n\nbinary formatted:\n",
    bin: [3u8, 5, 8, 13],
    // `{b}:` is The same as `bin:`
    {b}: [3u8, 5, 8, 13],

    "\n\nalternate-binary formatted:\n",
    alt_bin: [21u8, 34, 55, 89],
    // `{#b}:` is The same as `alt_bin:`
    {#b}: [21u8, 34, 55, 89],

    "\n\nhexadecimal formatted:\n",
    hex: [3u8, 5, 8, 13],
    // `{X}:` is The same as `hex:`
    {X}: [3u8, 5, 8, 13],

    "\n\nalternate-hexadecimal formatted:\n",
    alt_hex: [21u8, 34, 55, 89],
    // `{#X}:` is The same as `alt_hex:`
    {#X}: [21u8, 34, 55, 89],

    "\n\n",
};

The above code produces this compile-time error:

error[E0080]: evaluation of constant value failed
  --> src/macros.rs:186:15
   |
6  |   const _: () = concat_panic!{
   |  _______________^
7  | |     // the optional `$fmtarg` parameter.
8  | |     // If this argument isn't passed, it defaults to `FmtArg::DEBUG`
9  | |     FmtArg::ALT_DEBUG;
...  |
60 | |     "\n\n",
61 | | };
   | |_^ the evaluated program panicked at '

showing off literals:
100hello

non-literals with formatting determined by the $fmtarg parameter:
"a non-literal"[
    100,
    200,
]

explicitly debug formatted:
"foo""bar"

alternate debug formatted:
[
    "foo",
]"bar"

display formatted:
baz[qux, aaa]

alternate display formatted:[
    bbb,
    ccc,
][
    bbb,
    ccc,
]

binary formatted:
[11, 101, 1000, 1101][11, 101, 1000, 1101]

alternate-binary formatted:
[
    0b10101,
    0b100010,
    0b110111,
    0b1011001,
][
    0b10101,
    0b100010,
    0b110111,
    0b1011001,
]

hexadecimal formatted:
[3, 5, 8, D][3, 5, 8, D]

alternate-hexadecimal formatted:
[
    0x15,
    0x22,
    0x37,
    0x59,
][
    0x15,
    0x22,
    0x37,
    0x59,
]

', src/macros.rs:6:15
   |
   = note: this error originates in the macro `concat_panic` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error