Skip to content

Commit

Permalink
Merge pull request #195 from dtolnay/ensure
Browse files Browse the repository at this point in the history
Limit the debug outputs from ensure to 40 bytes
  • Loading branch information
dtolnay committed Nov 22, 2021
2 parents 9f2e32f + 4e4ada2 commit 4ff48fe
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
63 changes: 61 additions & 2 deletions src/ensure.rs
@@ -1,5 +1,9 @@
use crate::{anyhow, Error};
use core::fmt::Debug;
use core::fmt::{self, Debug, Display, Write};
use core::mem::MaybeUninit;
use core::ptr;
use core::slice;
use core::str;

#[doc(hidden)]
pub trait BothDebug {
Expand All @@ -12,7 +16,7 @@ where
B: Debug,
{
fn __dispatch_ensure(self, msg: &'static str) -> Error {
anyhow!("{} ({:?} vs {:?})", msg, self.0, self.1)
render(msg, &self.0, &self.1)
}
}

Expand All @@ -27,6 +31,61 @@ impl<A, B> NotBothDebug for &(A, B) {
}
}

struct Buf {
bytes: [MaybeUninit<u8>; 40],
written: usize,
}

impl Buf {
fn new() -> Self {
Buf {
bytes: [MaybeUninit::uninit(); 40],
written: 0,
}
}
}

impl Write for Buf {
fn write_str(&mut self, s: &str) -> fmt::Result {
let remaining = self.bytes.len() - self.written;
if s.len() <= remaining {
unsafe {
ptr::copy_nonoverlapping(
s.as_ptr(),
self.bytes.as_mut_ptr().add(self.written).cast::<u8>(),
s.len(),
);
}
self.written += s.len();
Ok(())
} else {
Err(fmt::Error)
}
}
}

impl Display for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(
self.bytes.as_ptr().cast::<u8>(),
self.written,
))
})
}
}

fn render(msg: &'static str, lhs: &dyn Debug, rhs: &dyn Debug) -> Error {
let mut lhs_buf = Buf::new();
if fmt::write(&mut lhs_buf, format_args!("{:?}", lhs)).is_ok() {
let mut rhs_buf = Buf::new();
if fmt::write(&mut rhs_buf, format_args!("{:?}", rhs)).is_ok() {
return anyhow!("{} ({} vs {})", msg, lhs_buf, rhs_buf);
}
}
Error::msg(msg)
}

#[doc(hidden)]
#[macro_export]
macro_rules! __parse_ensure {
Expand Down
12 changes: 12 additions & 0 deletions tests/test_ensure.rs
Expand Up @@ -365,3 +365,15 @@ fn test_trailer() {
"Condition failed: `err.is::<<str as ToOwned>::Owned>() == true` (false vs true)",
);
}

#[test]
fn test_too_long() {
let test = || Ok(ensure!("" == "x".repeat(10)));
assert_err(
test,
"Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")",
);

let test = || Ok(ensure!("" == "x".repeat(80)));
assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`");
}

0 comments on commit 4ff48fe

Please sign in to comment.