#[allow(unused_imports)]
use crate::*;
#[macro_export]
macro_rules! ASSERT {
($cond:expr, ($($fmt:tt)*) $(,$($args:expr),*)?) => {{
$crate::TRACE_NOBUG!(($($fmt)*) $(,$($args),*)?);
#[cfg(all(debug_assertions,test))] $crate::set_testing();
if !$cond {
$crate::DIE!(($($fmt)*) $(,$($args),*)?)
}
}};
($cond:expr, $fmt:literal $(,$($args:expr),*)?) => {{
$crate::TRACE_NOBUG!($fmt $(,$($args),*)?);
#[cfg(all(debug_assertions,test))] $crate::set_testing();
if !$cond {
$crate::DIE!($fmt $(,$($args),*)?)
}
}};
($cond:expr) => {{
$crate::TRACE_NOBUG!("ASSERTION FAILED: {}", stringify!($cond));
#[cfg(all(debug_assertions,test))] $crate::set_testing();
if !$cond {
$crate::DIE!("ASSERTION FAILED: {}", stringify!($cond))
}
}};
}
#[macro_export]
macro_rules! ASSERT_DBG {
($($tt:tt)*) => {
#[cfg(debug_assertions)]
$crate::ASSERT!($($tt)*);
}
}
#[test]
fn test_assert() {
ASSERT!(true);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "ASSERTION FAILED: false"]
fn test_assert1() {
ASSERT!(false);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "foo"]
fn test_assert2() {
ASSERT!(false, "foo");
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "foo 42"]
fn test_assert3() {
ASSERT!(false, "foo {}", 42);
}
#[macro_export]
macro_rules! ASSERT_ONCE {
($($code:tt)*) => {
{
$crate::ONCE!($crate::ASSERT!($($code)*));
true
}
};
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "ASSERTION FAILED"]
fn test_assert_once() {
ASSERT_ONCE!(false, "ASSERTION FAILED");
}
#[test]
#[cfg(debug_assertions)]
fn test_fixme_assert_once() {
for i in 0..10 {
FIXME!({ASSERT_ONCE!(i == 0)} "not to be used this way in real code");
}
}
#[macro_export]
macro_rules! REQUIRE {
([$($cond:expr $(, $fmt:literal $(,$args:expr)*)?;)*]) => {
$($crate::REQUIRE!($cond $(,$fmt $(,$args)*)?);)*
};
(const { $cond:expr } $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::CFG_IF! {
if #[cfg(feature = "const_expr")] {
$crate::ASSERT!(
(const { $cond }),
("PRECONDITION FAILED: {}" $(, ": ", $fmt)?),
stringify!($cond) $($(,$($args),*)?)?
);
} else {
const COND: bool = $cond;
$crate::ASSERT!(
COND,
("PRECONDITION FAILED: {}" $(, ": ", $fmt)?),
stringify!($cond) $($(,$($args),*)?)?
);
}
}
};
(($lhs:expr) == ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs == $rhs,
("PRECONDITION FAILED: {} == {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs)
};
(($lhs:expr) != ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs != $rhs,
("PRECONDITION FAILED: {} != {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs)
};
(($lhs:expr) < ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs < $rhs,
("PRECONDITION FAILED: {} < {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs)
};
(($lhs:expr) <= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs <= $rhs,
("PRECONDITION FAILED: {} <= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs)
};
(($lhs:expr) > ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs > $rhs,
("PRECONDITION FAILED: {} > {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs)
};
(($lhs:expr) >= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs >= $rhs,
("PRECONDITION FAILED: {} >= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs)
};
($cond:expr $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($cond, ("PRECONDITION FAILED: {}" $(, ": ", $fmt)?), stringify!($cond)
$($(, $($args),*)?)?)
};
}
#[macro_export]
macro_rules! REQUIRE_DBG {
($($tt:tt)*) => {
#[cfg(debug_assertions)]
$crate::REQUIRE!($($tt)*);
}
}
#[test]
fn test_require() {
let yes = true;
REQUIRE!(true);
REQUIRE!(const { true });
REQUIRE!((yes) == (true));
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "PRECONDITION FAILED: false"]
fn test_require1() {
REQUIRE!(false);
}
#[test]
fn test_braced() {
REQUIRE!({ true }, "foo {}", 42);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "PRECONDITION FAILED: false: foo"]
fn test_require2() {
REQUIRE!(false, "foo");
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "PRECONDITION FAILED: false: foo 42"]
fn test_require3() {
REQUIRE!(false, "foo {}", 42);
}
#[test]
#[cfg(debug_assertions)]
#[should_panic = "PRECONDITION FAILED: false: baz 43"]
fn test_require4() {
REQUIRE!([
true;
true, "bar";
false, "baz {}", 43;
]);
}
#[cfg(feature = "const_expr")]
#[cfg(debug_assertions)]
#[allow(clippy::items_after_test_module)]
#[cfg(test)]
mod test {
struct ConstGeneric<const N: i32>;
impl<const N: i32> ConstGeneric<N> {
fn new() -> Self {
REQUIRE!(const { N > 0 }, "N out of range");
Self
}
}
#[test]
#[should_panic(expected = "N out of range")]
fn test_const_generic() {
let _a = ConstGeneric::<1>::new();
let _b = ConstGeneric::<0>::new();
}
}
#[macro_export]
macro_rules! ENSURE {
(
[$($cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?);* $(;)?]
$result:ident = $code:expr) => {{
let mut early_return = true;
let $result = (|| {
let result = $code;
early_return = false;
result
})();
$($crate::ASSERT!($cond, ("POSTCONDITON FAILED: {}" $(, ": ", $fmt)?), stringify!($cond) $($(, $($args),*)?)?);)*
if early_return {
return $result;
}
$result
}};
(
$cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?;
$result:ident = $code:expr) => {{
let mut early_return = true;
let $result = (|| {
let result = $code;
early_return = false;
result
})();
$crate::ASSERT!($cond, ("POSTCONDITON FAILED: {}" $(, ": ", $fmt)?), stringify!($cond) $($(, $($args),*)?)?);
if early_return {
return $result;
}
$result
}};
}
#[macro_export]
macro_rules! ENSURE_DBG {
(
[$($cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?);* $(;)?]
$result:ident = $code:expr) => {
#[cfg(debug_assertions)]
$crate::ENSURE!(
[$($cond $(, $fmt $(, $($args),*)?)?);*]
$result = $code
);
#[cfg(not(debug_assertions))]
{$code}
};
(
$cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?;
$result:ident = $code:expr) => {
#[cfg(debug_assertions)]
$crate::ENSURE!(
$cond $(, $fmt $(, $($args),*)?)?;
$result = $code
);
#[cfg(not(debug_assertions))]
{$code}
};
}
#[macro_export]
macro_rules! CHECK {
([$($cond:expr $(, $fmt:literal $(,$args:expr)*)?;)*]) => {
$($crate::CHECK!($cond $(,$fmt $(,$args)*)?);)*
true
};
(const { $cond:expr } $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::CFG_IF! {
if #[cfg(feature = "const_expr")] {
$crate::ASSERT!(
(const { $cond }),
("TEST FAILED: {}" $(, ": ", $fmt)?),
stringify!($cond) $($(,$($args),*)?)?
);
true
} else {
const COND: bool = $cond;
$crate::ASSERT!(
COND,
("TEST FAILED: {}" $(, ": ", $fmt)?),
stringify!($cond) $($(,$($args),*)?)?
);
true
}
}
};
(($lhs:expr) == ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs == $rhs,
("TEST FAILED: {} == {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs);
true
};
(($lhs:expr) != ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs != $rhs,
("TEST FAILED: {} != {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs);
true
};
(($lhs:expr) < ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs < $rhs,
("TEST FAILED: {} < {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs);
true
};
(($lhs:expr) <= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs <= $rhs,
("TEST FAILED: {} <= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs);
true
};
(($lhs:expr) > ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs > $rhs,
("TEST FAILED: {} > {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs);
true
};
(($lhs:expr) >= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($lhs >= $rhs,
("TEST FAILED: {} >= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
stringify!($lhs), stringify!($rhs)
$($(, $($args),*)?)?, $lhs, $rhs);
true
};
($cond:expr $(, $fmt:literal $(, $($args:expr),*)?)?) => {
$crate::ASSERT!($cond, ("TEST FAILED: {}" $(, ": ", $fmt)?), stringify!($cond)
$($(, $($args),*)?)?);
true
};
}
#[test]
fn test_check() {
CHECK!(const { true });
}