1#[derive(Clone, Default)]
13pub struct Failed {
14 pub expr: &'static str,
15 pub file: &'static str,
16 pub line: u32,
17 pub col: u32,
18}
19
20#[macro_export]
23macro_rules! fail {
24 ($expr:expr) => {
25 return Err($crate::assert::Failed {
26 expr: $expr,
27 file: file!(),
28 line: line!(),
29 col: column!(),
30 });
31 };
32 () => {
33 $crate::fail!("test failed");
34 };
35}
36
37#[macro_export]
39macro_rules! assert {
40 (@inner $cond:expr, $msg:expr) => {
41 if !$cond {
42 let cond = stringify!($cond);
43 tracing::error!("assertion failed: `{cond}`{}, {}:{}:{}", $msg, file!(), line!(), column!());
44 $crate::fail!(cond)
45 }
46 };
47 ($cond:expr, $($msg:tt)+) => {
48 $crate::assert!(@inner $cond, format_args!("; ", format_args!($($msg)+)))
49 };
50 ($cond:expr $(,)?) => {
51 $crate::assert!(@inner $cond, "")
52 };
53}
54
55#[macro_export]
57macro_rules! assert_eq {
58 ($left:expr, $right:expr $(,)?) => {
59 $crate::assert_binop!($left, $right, ==)
60 };
61 ($left:expr, $right:expr, $($msg:tt)+) => {
62 $crate::assert_binop!($left, $right, ==, $($msg)+)
63 };
64}
65
66#[macro_export]
68macro_rules! assert_ne {
69 ($left:expr, $right:expr $(,)?) => {
70 $crate::assert_binop!($left, $right, !=)
71 };
72 ($left:expr, $right:expr, $($msg:tt)+) => {
73 $crate::assert_binop!($left, $right, !=, $($msg)+)
74 };
75}
76
77#[macro_export]
79macro_rules! assert_gt {
80 ($left:expr, $right:expr $(,)?) => {
81 $crate::assert_binop!($left, $right, >)
82 };
83 ($left:expr, $right:expr, $($msg:tt)*) => {
84 $crate::assert_binop!($left, $right, >, $($msg)*)
85 };
86}
87
88#[macro_export]
90macro_rules! assert_lt {
91 ($left:expr, $right:expr $(,)?) => {
92 $crate::assert_binop!($left, $right, <)
93 };
94 ($left:expr, $right:expr, $($msg:tt)*) => {
95 $crate::assert_binop!($left, $right, <, $($msg)*)
96 };
97}
98
99#[macro_export]
101macro_rules! assert_gte {
102 ($left:expr, $right:expr $(,)?) => {
103 $crate::assert_binop!($left, $right, >=)
104 };
105 ($left:expr, $right:expr, $($msg:tt)*) => {
106 $crate::assert_binop!($left, $right, >=, $($msg)*)
107 };
108}
109
110#[macro_export]
112macro_rules! assert_lte {
113 ($left:expr, $right:expr $(,)?) => {
114 $crate::assert_binop!($left, $right, <=)
115 };
116 ($left:expr, $right:expr, $($msg:tt)*) => {
117 $crate::assert_binop!($left, $right, <=, $($msg)*)
118 };
119}
120
121#[doc(hidden)]
122#[macro_export]
123macro_rules! assert_binop {
124 ($left:expr, $right:expr, $binop:tt) => {
125 $crate::assert_binop!(@inner $left, $right, $binop, "")
126 };
127 ($left:expr, $right:expr, $binop:tt, $($msg:tt)+) => {
128 $crate::assert_binop!(@inner $left, $right, $binop, ": {}", format_args!($($msg)+))
129 };
130 (@inner $left:expr, $right:expr, $binop:tt, $($msg:tt)+) => {
131 let left = $left;
132 let right = $right;
133 if !(left $binop right) {
134 let condition = concat!(stringify!($left), " ", stringify!($binop), " ", stringify!($right));
135 tracing::error!(
136 "assertion failed: `{condition}`\n left: `{:?}`,\n right: `{:?}`{}, {}:{}:{}",
137 left, right, format_args!($($msg)+), file!(), line!(), column!()
138 );
139 $crate::fail!(condition)
140 }
141 };
142}
143
144impl core::fmt::Debug for Failed {
145 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
146 let Self {
147 expr,
148 file,
149 line,
150 col,
151 } = self;
152 write!(f, "assertion failed: `{expr}`, {file}:{line}:{col}",)
153 }
154}