1#[cfg(feature = "full")]
2#[doc(hidden)]
3#[macro_export]
4macro_rules! function {
5 ($static:ident) => {
6 use $crate::once_cell::sync::Lazy;
19 fn _f() {}
20 static $static: $crate::once_cell::sync::Lazy<&'static str> =
21 $crate::once_cell::sync::Lazy::new(|| {
22 fn type_name_of<T>(_: T) -> &'static str {
23 ::std::any::type_name::<T>()
24 }
25 let name = type_name_of(_f);
26 &name[..name.len() - 4]
27 });
28 };
29}
30
31#[cfg(feature = "full")]
33#[doc(hidden)]
34#[macro_export]
35macro_rules! assert_helper {
36 (condition = $condition:expr, $message:literal, $(details = $details:expr)?, $assert_type:path, $display_type:literal, must_hit = $must_hit:literal) => {{
39 let condition = $condition;
41 let details = &$crate::serde_json::json!({});
42 $(let details = $details;)?
43
44 $crate::function!(FUN_NAME);
45
46 use $crate::assert::AssertionCatalogInfo;
47 #[$crate::linkme::distributed_slice($crate::assert::ANTITHESIS_CATALOG)]
48 #[linkme(crate = $crate::linkme)] static ALWAYS_CATALOG_ITEM: AssertionCatalogInfo = AssertionCatalogInfo {
50 assert_type: $assert_type,
51 display_type: $display_type,
52 condition: false,
53 message: $message,
54 class: ::std::module_path!(),
55 function: &FUN_NAME, file: ::std::file!(),
57 begin_line: ::std::line!(),
58 begin_column: ::std::column!(),
59 must_hit: $must_hit,
60 id: $message,
61 };
62
63 let ptr_function = Lazy::force(&FUN_NAME);
64
65 $crate::assert::assert_impl(
66 $assert_type, $display_type.to_owned(), condition, $message.to_owned(), ::std::module_path!().to_owned(), String::from(*ptr_function), ::std::file!().to_owned(), ::std::line!(), ::std::column!(), true, $must_hit, $message.to_owned(), details, )
80 }}; }
82
83#[cfg(not(feature = "full"))]
84#[doc(hidden)]
85#[macro_export]
86macro_rules! assert_helper {
87 (condition = $condition:expr, $message:literal, $(details = $details:expr)?, $assert_type:path, $display_type:literal, must_hit = $must_hit:literal) => {{
88 let condition = $condition;
93 $(let details = $details;)?
94 }};
95}
96
97#[macro_export]
112macro_rules! assert_always {
113 ($condition:expr, $message:literal$(, $details:expr)?) => {
114 $crate::assert_helper!(
115 condition = $condition,
116 $message,
117 $(details = $details)?,
118 $crate::assert::AssertType::Always,
119 "Always",
120 must_hit = true
121 )
122 };
123 ($($rest:tt)*) => {
124 ::std::compile_error!(
125r#"Invalid syntax when calling macro `assert_always`.
126Example usage:
127 `assert_always!(condition_expr, "assertion message (static literal)", &details_json_value_expr)`
128"#
129 );
130 };
131}
132
133#[macro_export]
148macro_rules! assert_always_or_unreachable {
149 ($condition:expr, $message:literal$(, $details:expr)?) => {
150 $crate::assert_helper!(
151 condition = $condition,
152 $message,
153 $(details = $details)?,
154 $crate::assert::AssertType::Always,
155 "AlwaysOrUnreachable",
156 must_hit = false
157 )
158 };
159 ($($rest:tt)*) => {
160 ::std::compile_error!(
161r#"Invalid syntax when calling macro `assert_always_or_unreachable`.
162Example usage:
163 `assert_always_or_unreachable!(condition_expr, "assertion message (static literal)", &details_json_value_expr)`
164"#
165 );
166 };
167}
168
169#[macro_export]
185macro_rules! assert_sometimes {
186 ($condition:expr, $message:literal$(, $details:expr)?) => {
187 $crate::assert_helper!(
188 condition = $condition,
189 $message,
190 $(details = $details)?,
191 $crate::assert::AssertType::Sometimes,
192 "Sometimes",
193 must_hit = true
194 )
195 };
196 ($($rest:tt)*) => {
197 ::std::compile_error!(
198r#"Invalid syntax when calling macro `assert_sometimes`.
199Example usage:
200 `assert_sometimes!(condition_expr, "assertion message (static literal)", &details_json_value_expr)`
201"#
202 );
203 };
204}
205
206#[macro_export]
224macro_rules! assert_reachable {
225 ($message:literal$(, $details:expr)?) => {
226 $crate::assert_helper!(
227 condition = true,
228 $message,
229 $(details = $details)?,
230 $crate::assert::AssertType::Reachability,
231 "Reachable",
232 must_hit = true
233 )
234 };
235 ($($rest:tt)*) => {
236 ::std::compile_error!(
237r#"Invalid syntax when calling macro `assert_reachable`.
238Example usage:
239 `assert_reachable!("assertion message (static literal)", &details_json_value_expr)`
240"#
241 );
242 };
243}
244
245#[macro_export]
264macro_rules! assert_unreachable {
265 ($message:literal$(, $details:expr)?) => {
266 $crate::assert_helper!(
267 condition = false,
268 $message,
269 $(details = $details)?,
270 $crate::assert::AssertType::Reachability,
271 "Unreachable",
272 must_hit = false
273 )
274 };
275 ($($rest:tt)*) => {
276 ::std::compile_error!(
277r#"Invalid syntax when calling macro `assert_unreachable`.
278Example usage:
279 `assert_unreachable!("assertion message (static literal)", &details_json_value_expr)`
280"#
281 );
282 };
283}
284
285#[cfg(feature = "full")]
286#[doc(hidden)]
287#[macro_export]
288macro_rules! guidance_helper {
289 ($guidance_type:expr, $message:literal, $maximize:literal, $guidance_data:expr) => {
290 $crate::function!(FUN_NAME);
291
292 use $crate::assert::guidance::{GuidanceCatalogInfo, GuidanceType};
293 #[$crate::linkme::distributed_slice($crate::assert::ANTITHESIS_GUIDANCE_CATALOG)]
294 #[linkme(crate = $crate::linkme)] static GUIDANCE_CATALOG_ITEM: GuidanceCatalogInfo = GuidanceCatalogInfo {
296 guidance_type: $guidance_type,
297 message: $message,
298 id: $message,
299 class: ::std::module_path!(),
300 function: &FUN_NAME,
301 file: ::std::file!(),
302 begin_line: ::std::line!(),
303 begin_column: ::std::column!(),
304 maximize: $maximize,
305 };
306
307 $crate::assert::guidance::guidance_impl(
308 $guidance_type,
309 $message.to_owned(),
310 $message.to_owned(),
311 ::std::module_path!().to_owned(),
312 Lazy::force(&FUN_NAME).to_string(),
313 ::std::file!().to_owned(),
314 ::std::line!(),
315 ::std::column!(),
316 $maximize,
317 $guidance_data,
318 true,
319 )
320 };
321}
322
323#[cfg(feature = "full")]
324#[doc(hidden)]
325#[macro_export]
326macro_rules! numeric_guidance_helper {
327 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:literal$(, $details:expr)?) => {{
328 let left = $left;
329 let right = $right;
330 let details = &$crate::serde_json::json!({});
331 $(let details = $details;)?
332 let mut details = details.clone();
333 details["left"] = left.into();
334 details["right"] = right.into();
335 $assert!(left $op right, $message, &details);
336
337 let guidance_data = $crate::serde_json::json!({
338 "left": left,
339 "right": right,
340 });
341 let diff = $crate::assert::guidance::Diff::diff(&left, right);
355 type Guard<T> = $crate::assert::guidance::Guard<$maximize, T>;
356 type Distance = f64;
359 static GUARD: Guard<Distance> = Guard::init();
360 if GUARD.should_emit(diff) {
361 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Numeric, $message, $maximize, guidance_data);
362 }
363 }};
364}
365
366#[cfg(not(feature = "full"))]
367#[doc(hidden)]
368#[macro_export]
369macro_rules! numeric_guidance_helper {
370 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
371 assert!($left $op $right, $message$(, $details)?);
372 };
373}
374
375#[cfg(feature = "full")]
376#[doc(hidden)]
377#[macro_export]
378macro_rules! boolean_guidance_helper {
379 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:literal$(, $details:expr)?) => {{
380 let details = &$crate::serde_json::json!({});
381 $(let details = $details;)?
382 let mut details = details.clone();
383 let (cond, guidance_data) = {
384 $(let $name = $cond;)*
385 $(details[::std::stringify!($name)] = $name.into();)*
386 (
387 if $all { true $(&& $name)* } else { false $(|| $name)* },
388 $crate::serde_json::json!({$(::std::stringify!($name): $name),*})
389 )
390 };
391 $assert!(cond, $message, &details);
392 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Boolean, $message, $all, guidance_data);
393 }};
394}
395
396#[cfg(not(feature = "full"))]
397#[doc(hidden)]
398#[macro_export]
399macro_rules! boolean_guidance_helper {
400 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:literal$(, $details:expr)?) => {{
401 let cond = {
402 $(let $name = $cond;)*
403 if $all { true $(&& $name)* } else { false $(|| $name)* }
404 };
405 $assert!(cond, $message$(, $details)?);
406 }};
407}
408
409#[macro_export]
411macro_rules! assert_always_greater_than {
412 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
413 $crate::numeric_guidance_helper!($crate::assert_always, >, false, $left, $right, $message$(, $details)?)
414 };
415 ($($rest:tt)*) => {
416 ::std::compile_error!(
417r#"Invalid syntax when calling macro `assert_always_greater_than`.
418Example usage:
419 `assert_always_greater_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
420"#
421 );
422 };
423}
424
425#[macro_export]
427macro_rules! assert_always_greater_than_or_equal_to {
428 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
429 $crate::numeric_guidance_helper!($crate::assert_always, >=, false, $left, $right, $message$(, $details)?)
430 };
431 ($($rest:tt)*) => {
432 ::std::compile_error!(
433r#"Invalid syntax when calling macro `assert_always_greater_than_or_equal_to`.
434Example usage:
435 `assert_always_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
436"#
437 );
438 };
439}
440
441#[macro_export]
443macro_rules! assert_always_less_than {
444 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
445 $crate::numeric_guidance_helper!($crate::assert_always, <, true, $left, $right, $message$(, $details)?)
446 };
447 ($($rest:tt)*) => {
448 ::std::compile_error!(
449r#"Invalid syntax when calling macro `assert_always_less_than`.
450Example usage:
451 `assert_always_less_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
452"#
453 );
454 };
455}
456
457#[macro_export]
459macro_rules! assert_always_less_than_or_equal_to {
460 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
461 $crate::numeric_guidance_helper!($crate::assert_always, <=, true, $left, $right, $message$(, $details)?)
462 };
463 ($($rest:tt)*) => {
464 ::std::compile_error!(
465r#"Invalid syntax when calling macro `assert_always_less_than_or_equal_to`.
466Example usage:
467 `assert_always_less_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
468"#
469 );
470 };
471}
472
473#[macro_export]
475macro_rules! assert_sometimes_greater_than {
476 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
477 $crate::numeric_guidance_helper!($crate::assert_sometimes, >, true, $left, $right, $message$(, $details)?)
478 };
479 ($($rest:tt)*) => {
480 ::std::compile_error!(
481r#"Invalid syntax when calling macro `assert_sometimes_greater_than`.
482Example usage:
483 `assert_sometimes_greater_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
484"#
485 );
486 };
487}
488
489#[macro_export]
491macro_rules! assert_sometimes_greater_than_or_equal_to {
492 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
493 $crate::numeric_guidance_helper!($crate::assert_sometimes, >=, true, $left, $right, $message$(, $details)?)
494 };
495 ($($rest:tt)*) => {
496 ::std::compile_error!(
497r#"Invalid syntax when calling macro `assert_sometimes_greater_than_or_equal_to`.
498Example usage:
499 `assert_sometimes_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
500"#
501 );
502 };
503}
504
505#[macro_export]
507macro_rules! assert_sometimes_less_than {
508 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
509 $crate::numeric_guidance_helper!($crate::assert_sometimes, <, false, $left, $right, $message$(, $details)?)
510 };
511 ($($rest:tt)*) => {
512 ::std::compile_error!(
513r#"Invalid syntax when calling macro `assert_sometimes_less_than`.
514Example usage:
515 `assert_sometimes_less_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
516"#
517 );
518 };
519}
520
521#[macro_export]
523macro_rules! assert_sometimes_less_than_or_equal_to {
524 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
525 $crate::numeric_guidance_helper!($crate::assert_sometimes, <=, false, $left, $right, $message$(, $details)?)
526 };
527 ($($rest:tt)*) => {
528 ::std::compile_error!(
529r#"Invalid syntax when calling macro `assert_sometimes_less_than_or_equal_to`.
530Example usage:
531 `assert_sometimes_less_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
532"#
533 );
534 };
535}
536
537#[macro_export]
542macro_rules! assert_always_some {
543 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:literal$(, $details:expr)?) => {
544 $crate::boolean_guidance_helper!($crate::assert_always, false, {$($($name: $cond),+)?}, $message$(, $details)?);
545 };
546 ($($rest:tt)*) => {
547 ::std::compile_error!(
548r#"Invalid syntax when calling macro `assert_always_some`.
549Example usage:
550 `assert_always_some!({field1: cond1, field2: cond2, ...}, "assertion message (static literal)", &details_json_value_expr)`
551"#
552 );
553 };
554}
555
556#[macro_export]
561macro_rules! assert_sometimes_all {
562 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:literal$(, $details:expr)?) => {
563 $crate::boolean_guidance_helper!($crate::assert_sometimes, true, {$($($name: $cond),+)?}, $message$(, $details)?);
564 };
565 ($($rest:tt)*) => {
566 ::std::compile_error!(
567r#"Invalid syntax when calling macro `assert_sometimes_all`.
568Example usage:
569 `assert_sometimes_all!({field1: cond1, field2: cond2, ...}, "assertion message (static literal)", &details_json_value_expr)`
570"#
571 );
572 };
573}