Skip to content

Commit

Permalink
Add concat_panic_truncate function and macro, to allow panics with a …
Browse files Browse the repository at this point in the history
…configurable max upper bound
  • Loading branch information
dgarrett committed Oct 28, 2024
1 parent 23b8eaf commit 3d802ee
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
35 changes: 30 additions & 5 deletions src/concat_panic_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,34 @@ pub const fn concat_panic(args: &[&[PanicVal<'_>]]) -> ! {
//
// Also, given that most(?) panic messages are smaller than 1024 bytes long,
// it's not going to be any less efficient in the common case.
if let Err(_) = panic_inner::<1024>(args) {}
if let Err(_) = panic_inner::<1024, MAX_PANIC_MSG_LEN>(args) {}

if let Err(_) = panic_inner::<{ 1024 * 6 }>(args) {}
if let Err(_) = panic_inner::<{ 1024 * 6 }, MAX_PANIC_MSG_LEN>(args) {}

match panic_inner::<MAX_PANIC_MSG_LEN>(args) {
match panic_inner::<MAX_PANIC_MSG_LEN, MAX_PANIC_MSG_LEN>(args) {
Ok(x) => match x {},
Err(_) => panic!(
"\
unreachable:\n\
the `write_panicval_to_buffer` macro must not return Err when \
$capacity == $max_capacity\
"
),
}
}

/// Panics by concatenating the argument slice. Limited to a max
/// `PANIC_MSG_LEN`, after which the message will be truncated.
///
/// See [`const_panic_truncate`] for details on parameters.
///
/// This is the function that the
/// [`concat_panic_truncate`](macro@concat_panic_truncat) macro calls to panic.
#[cold]
#[inline(never)]
#[track_caller]
pub const fn concat_panic_truncate<const PANIC_MSG_LEN: usize>(args: &[&[PanicVal<'_>]]) -> ! {
match panic_inner::<PANIC_MSG_LEN, PANIC_MSG_LEN>(args) {
Ok(x) => match x {},
Err(_) => panic!(
"\
Expand Down Expand Up @@ -243,7 +266,9 @@ macro_rules! make_buffer_writer_macros {
#[cold]
#[inline(never)]
#[track_caller]
const fn panic_inner<const LEN: usize>(args: &[&[PanicVal<'_>]]) -> Result<Never, NotEnoughSpace> {
const fn panic_inner<const LEN: usize, const MAX_LEN: usize>(
args: &[&[PanicVal<'_>]],
) -> Result<Never, NotEnoughSpace> {
let mut buffer = [0u8; LEN];
let mut len = 0usize;

Expand All @@ -252,7 +277,7 @@ const fn panic_inner<const LEN: usize>(args: &[&[PanicVal<'_>]]) -> Result<Never
write_to_buffer! {
args
(
len, LEN, MAX_PANIC_MSG_LEN, Err(NotEnoughSpace),
len, LEN, MAX_LEN, Err(NotEnoughSpace),
write_buffer, write_buffer_checked,
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ mod fmt_impls {
}

pub use crate::{
concat_panic_::{concat_panic, MAX_PANIC_MSG_LEN},
concat_panic_::{concat_panic, concat_panic_truncate, MAX_PANIC_MSG_LEN},
panic_val::PanicVal,
wrapper::StdWrapper,
};
Expand Down
15 changes: 15 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,21 @@ macro_rules! concat_panic {
)
}

/// Panics with the concanenation of the arguments, truncating after the max
/// length passed as the first argument to the macro.
///
/// See [`concat_panic`] for more details.
#[macro_export]
macro_rules! concat_panic_truncate {
($max_len:expr, $($args:tt)*) => (
$crate::__concat_func_setup!{
(|args| $crate::concat_panic_truncate::<$max_len>(args))
[]
[$($args)*,]
}
)
}

// This macro takes the optional `$fmt:expr;` argument before everything else.
// But I had to parse the argument manually,
// because `$fmt:expr;` fails compilation instead of trying the following branches
Expand Down

0 comments on commit 3d802ee

Please sign in to comment.