dfir_rs/
declarative_macro.rs
1#[macro_export]
5macro_rules! rassert {
6 ($cond:expr $(,)?) => {
7 $crate::rassert!($cond, "assertion failed: `{}`", stringify!($cond))
8 };
9 ($cond:expr, $fmt:literal) => {
10 $crate::rassert!($cond, $fmt,)
11 };
12 ($cond:expr, $fmt:literal, $($arg:tt)*) => {
13 {
14 if $cond {
15 Ok(())
16 }
17 else {
18 Err(format!($fmt, $($arg)*))
19 }
20 }
21 };
22}
23
24#[macro_export]
26macro_rules! rassert_eq {
27 ($a:expr, $b:expr) => {
28 $crate::rassert!($a == $b,)
29 };
30 ($a:expr, $b:expr, $($arg:tt)*) => {
31 $crate::rassert!($a == $b, $($arg)*)
32 };
33}
34
35#[macro_export]
37macro_rules! assert_var_impl {
38 ($var:ident: $($trait:path),+ $(,)?) => {
39 let _ = || {
40 fn assert_var_impl<T: ?Sized $(+ $trait)+>(_x: &T) {}
42 assert_var_impl(& $var);
43 };
44 };
45}
46
47#[macro_export]
51macro_rules! dfir_expect_warnings {
52 (
53 $hf:tt,
54 $( $msg:literal ),*
55 $( , )?
56 ) => {
57 {
58 fn emit(msg: impl ::std::convert::AsRef<str>) {
59 if Ok("ignore") == ::std::env::var("DFIR_EXPECT_WARNINGS").as_deref() {
60 eprintln!("{}", msg.as_ref());
61 } else {
62 panic!("{}", msg.as_ref());
63 }
64 }
65
66 let __file = ::std::file!();
67 let __line = ::std::line!() as usize;
68 let __hf = $crate::dfir_syntax_noemit! $hf;
69
70 let actuals = __hf.diagnostics().expect("Expected `diagnostics()` to be set.");
71 let actuals_len = actuals.len();
72 let actuals = ::std::collections::BTreeSet::from_iter(actuals.iter().cloned().map(|mut actual| {
73 actual.span.line = actual.span.line.saturating_sub(__line);
74 ::std::borrow::Cow::<'static, str>::Owned(actual.to_string().replace(__file, "$FILE"))
75 }));
76
77 let expecteds = [
78 $(
79 ::std::borrow::Cow::Borrowed( $msg ),
80 )*
81 ];
82 let expecteds_len = expecteds.len();
83 let expecteds = ::std::collections::BTreeSet::from(expecteds);
84
85 let missing_errs = expecteds.difference(&actuals).map(|missing| {
86 format!("Expected diagnostic `{}` was not emitted.", missing)
87 });
88 let extra_errs = actuals.difference(&expecteds).map(|extra| {
89 format!("Unexpected extra diagnostic `{}` was emitted", extra)
90 });
91 let all_errs: ::std::vec::Vec<_> = missing_errs.chain(extra_errs).collect();
92 if !all_errs.is_empty() {
93 emit(all_errs.join("\n"));
94 }
95
96 if actuals_len != expecteds_len {
97 emit(format!(
98 "Number of expected warnings ({}) does not match number of actual warnings ({}), were there duplicates?",
99 expecteds_len,
100 actuals_len
101 ));
102 }
103
104 __hf
105 }
106 };
107}
108
109#[doc(hidden)]
111#[macro_export]
112macro_rules! assert_graphvis_snapshots {
113 ($df:ident) => {
114 {
115 #[cfg(not(target_arch = "wasm32"))]
116 {
117 insta::with_settings!({snapshot_suffix => "graphvis_mermaid"}, {
118 insta::assert_snapshot!($df.meta_graph().unwrap().to_mermaid(&Default::default()));
119 });
120 insta::with_settings!({snapshot_suffix => "graphvis_dot"}, {
121 insta::assert_snapshot!($df.meta_graph().unwrap().to_dot(&Default::default()));
122 });
123 }
124 }
125 }
126}
127
128#[doc(hidden)]
129#[macro_export]
130#[cfg(feature = "python")]
131macro_rules! __python_feature_gate {
132 (
133 {
134 $( $ypy:tt )*
135 },
136 {
137 $( $npy:tt )*
138 }
139 ) => {
140 $( $ypy )*
141 };
142}
143
144#[doc(hidden)]
145#[macro_export]
146#[cfg(not(feature = "python"))]
147macro_rules! __python_feature_gate {
148 (
149 {
150 $( $ypy:tt )*
151 },
152 {
153 $( $npy:tt )*
154 }
155 ) => {
156 $( $npy )*
157 };
158}