Macro const_panic::impl_panicfmt [−][src]
macro_rules! impl_panicfmt {
(impl $type : path ; $(lifetime = $lt : lifetime ;) ? struct $typename : ident
$({ $($braced : tt) * }) ? $(($($tupled : tt) *)) ? $(;) ?) => { ... };
(impl $type : path ; $(lifetime = $lt : lifetime ;) ? enum $typename : ident
{
$($variant : ident $({ $($braced : tt) * }) ? $(($($tupled : tt) *)) ?),
* $(,) ?
}) => { ... };
}
This is supported on crate feature
non_basic
only.Expand description
Implements the PanicFmt
trait and the to_panicvals
method it requires.
This macro only accepts concrete types, and types with '_
lifetime arguments,
because it uses them in places where generic types don’t yet work.
Examples
Struct formatting
use const_panic::{ArrayString, FmtArg, impl_panicfmt};
fn main(){
let foo = Foo {
x: &[3, 5, 8, 13],
y: 21,
z: Bar(false, true),
};
assert_eq!(
ArrayString::<100>::from_panicvals(&foo.to_panicvals(FmtArg::DEBUG)).unwrap(),
"Foo { x: [3, 5, 8, 13], y: 21, z: Bar(false, true) }",
);
assert_eq!(
ArrayString::<200>::from_panicvals(&foo.to_panicvals(FmtArg::ALT_DEBUG)).unwrap(),
concat!(
"Foo {\n",
" x: [\n",
" 3,\n",
" 5,\n",
" 8,\n",
" 13,\n",
" ],\n",
" y: 21,\n",
" z: Bar(\n",
" false,\n",
" true,\n",
" ),\n",
"}",
),
);
}
struct Foo<'a> {
x: &'a [u8],
y: u8,
z: Bar,
}
// Implementing `PanicFmt` and the `to_panicvals` method for
// `Foo<'a>` (with any lifetime).
//
// Only `Foo<'_>` or `Foo<'static>` can work here, due to what the macro expands into.
impl_panicfmt!{
impl Foo<'_>;
struct Foo {
// removing all lifetimes in fields (or replacing them with `'_`) is required
x: &[u8],
y: u8,
z: Bar,
}
}
struct Bar(bool, bool);
impl_panicfmt!{
impl Bar;
struct Bar(bool, bool)
}
Enum Formatting
use const_panic::{ArrayString, FmtArg, impl_panicfmt};
fn main() {
let up: Qux<u8> = Qux::Up;
// Debug formatting the Up variant
assert_eq!(
ArrayString::<100>::from_panicvals(&up.to_panicvals(FmtArg::DEBUG)).unwrap(),
"Up",
);
let down: Qux<u16> = Qux::Down { x: 21, y: 34, z: 55 };
// Debug formatting the Down variant
assert_eq!(
ArrayString::<100>::from_panicvals(&down.to_panicvals(FmtArg::DEBUG)).unwrap(),
"Down { x: 21, y: 34, z: 55 }",
);
// Alternate-Debug formatting the Down variant
assert_eq!(
ArrayString::<100>::from_panicvals(&down.to_panicvals(FmtArg::ALT_DEBUG)).unwrap(),
concat!(
"Down {\n",
" x: 21,\n",
" y: 34,\n",
" z: 55,\n",
"}",
)
);
let left: Qux<u32> = Qux::Left(89);
// Debug formatting the Left variant
assert_eq!(
ArrayString::<100>::from_panicvals(&left.to_panicvals(FmtArg::DEBUG)).unwrap(),
"Left(89)",
);
// Alternate-Debug formatting the Left variant
assert_eq!(
ArrayString::<100>::from_panicvals(&left.to_panicvals(FmtArg::ALT_DEBUG)).unwrap(),
concat!(
"Left(\n",
" 89,\n",
")",
)
);
}
enum Qux<T> {
Up,
Down { x: T, y: T, z: T },
Left(u64),
}
// Because of limitations of stable const evaluation,
// you have to use macros to invoke the `impl_panicfmt` macro
// for more than one concrete type.
//
// This macro invocation implements panic formatting for
// - `Qux<u8>`
// - `Qux<u16>`
// - `Qux<u32>`
const_panic::inline_macro! {
(u8),
(u16),
(u32);
($T:ty) =>
impl_panicfmt!{
impl Qux<$T>;
// causes the returned `PanicVal`s from `Qux::to_panicvals`
// to be `PanicVal<'static>` instead of `PanicVal<'_>`
// (the default is that it borrows from the `self` argument)
lifetime = 'static;
enum Qux {
Up,
Down { x: $T, y: $T, z: $T },
Left(u64),
}
}
}