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:expr, $(details = $details:expr)?, $assert_type:path, $display_type:literal, must_hit = $must_hit:literal) => {{
39 const _: &str = $message;
41
42 let condition = $condition;
44 let details = &$crate::serde_json::Value::Null;
45 $(let details = $details;)?
46
47 $crate::function!(FUN_NAME);
48
49 use $crate::assert::AssertionCatalogInfo;
50 #[$crate::linkme::distributed_slice($crate::assert::ANTITHESIS_CATALOG)]
51 #[linkme(crate = $crate::linkme)] static ALWAYS_CATALOG_ITEM: AssertionCatalogInfo = AssertionCatalogInfo {
53 assert_type: $assert_type,
54 display_type: $display_type,
55 condition: false,
56 message: $message,
57 class: ::std::module_path!(),
58 function: &FUN_NAME, file: ::std::file!(),
60 begin_line: ::std::line!(),
61 begin_column: ::std::column!(),
62 must_hit: $must_hit,
63 id: $message,
64 };
65
66 let ptr_function = Lazy::force(&FUN_NAME);
67
68 static TRACKER: $crate::assert::TrackingInfo = $crate::assert::TrackingInfo::new();
69
70 $crate::assert::assert_impl(
71 $assert_type, $display_type, condition, $message, ::std::module_path!(), *ptr_function, ::std::file!(), ::std::line!(), ::std::column!(), true, $must_hit, $message, details, Some(&TRACKER), )
86 }}; }
88
89#[cfg(not(feature = "full"))]
90#[doc(hidden)]
91#[macro_export]
92macro_rules! assert_helper {
93 (condition = $condition:expr, $message:expr, $(details = $details:expr)?, $assert_type:path, $display_type:literal, must_hit = $must_hit:literal) => {{
94 const _: &str = $message;
96
97 let condition = $condition;
102 $(let details = $details;)?
103 }};
104}
105
106#[macro_export]
154macro_rules! assert_always {
155 ($condition:expr, $message:expr$(, $details:expr)?) => {
156 $crate::assert_helper!(
157 condition = $condition,
158 $message,
159 $(details = $details)?,
160 $crate::assert::AssertType::Always,
161 "Always",
162 must_hit = true
163 )
164 };
165 ($($rest:tt)*) => {
166 ::std::compile_error!(
167r#"Invalid syntax when calling macro `assert_always`.
168Example usage:
169 `assert_always!(condition_expr, "assertion message (const &'static str)", &details_json_value_expr)`
170"#
171 );
172 };
173}
174
175#[macro_export]
196macro_rules! assert_always_or_unreachable {
197 ($condition:expr, $message:expr$(, $details:expr)?) => {
198 $crate::assert_helper!(
199 condition = $condition,
200 $message,
201 $(details = $details)?,
202 $crate::assert::AssertType::Always,
203 "AlwaysOrUnreachable",
204 must_hit = false
205 )
206 };
207 ($($rest:tt)*) => {
208 ::std::compile_error!(
209r#"Invalid syntax when calling macro `assert_always_or_unreachable`.
210Example usage:
211 `assert_always_or_unreachable!(condition_expr, "assertion message (const &'static str)", &details_json_value_expr)`
212"#
213 );
214 };
215}
216
217#[macro_export]
238macro_rules! assert_sometimes {
239 ($condition:expr, $message:expr$(, $details:expr)?) => {
240 $crate::assert_helper!(
241 condition = $condition,
242 $message,
243 $(details = $details)?,
244 $crate::assert::AssertType::Sometimes,
245 "Sometimes",
246 must_hit = true
247 )
248 };
249 ($($rest:tt)*) => {
250 ::std::compile_error!(
251r#"Invalid syntax when calling macro `assert_sometimes`.
252Example usage:
253 `assert_sometimes!(condition_expr, "assertion message (const &'static str)", &details_json_value_expr)`
254"#
255 );
256 };
257}
258
259#[macro_export]
282macro_rules! assert_reachable {
283 ($message:expr$(, $details:expr)?) => {
284 $crate::assert_helper!(
285 condition = true,
286 $message,
287 $(details = $details)?,
288 $crate::assert::AssertType::Reachability,
289 "Reachable",
290 must_hit = true
291 )
292 };
293 ($($rest:tt)*) => {
294 ::std::compile_error!(
295r#"Invalid syntax when calling macro `assert_reachable`.
296Example usage:
297 `assert_reachable!("assertion message (const &'static str)", &details_json_value_expr)`
298"#
299 );
300 };
301}
302
303#[macro_export]
326macro_rules! assert_unreachable {
327 ($message:expr$(, $details:expr)?) => {
328 $crate::assert_helper!(
329 condition = false,
330 $message,
331 $(details = $details)?,
332 $crate::assert::AssertType::Reachability,
333 "Unreachable",
334 must_hit = false
335 )
336 };
337 ($($rest:tt)*) => {
338 ::std::compile_error!(
339r#"Invalid syntax when calling macro `assert_unreachable`.
340Example usage:
341 `assert_unreachable!("assertion message (const &'static str)", &details_json_value_expr)`
342"#
343 );
344 };
345}
346
347#[cfg(feature = "full")]
350#[doc(hidden)]
351#[macro_export]
352macro_rules! guidance_helper {
353 ($guidance_type:expr, $message:expr, $maximize:literal, $guidance_data:expr) => {
354 const _: &str = $message;
356
357 $crate::function!(FUN_NAME);
358
359 use $crate::assert::guidance::{GuidanceCatalogInfo, GuidanceType};
360 #[$crate::linkme::distributed_slice($crate::assert::ANTITHESIS_GUIDANCE_CATALOG)]
361 #[linkme(crate = $crate::linkme)] static GUIDANCE_CATALOG_ITEM: GuidanceCatalogInfo = GuidanceCatalogInfo {
363 guidance_type: $guidance_type,
364 message: $message,
365 id: $message,
366 class: ::std::module_path!(),
367 function: &FUN_NAME,
368 file: ::std::file!(),
369 begin_line: ::std::line!(),
370 begin_column: ::std::column!(),
371 maximize: $maximize,
372 };
373
374 $crate::assert::guidance::guidance_impl(
375 $guidance_type,
376 $message,
377 $message,
378 ::std::module_path!(),
379 *Lazy::force(&FUN_NAME),
380 ::std::file!(),
381 ::std::line!(),
382 ::std::column!(),
383 $maximize,
384 $guidance_data,
385 true,
386 )
387 };
388}
389
390#[cfg(feature = "full")]
391#[doc(hidden)]
392#[macro_export]
393macro_rules! numeric_guidance_helper {
394 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:expr$(, $details:expr)?) => {{
395 let left = $left;
396 let right = $right;
397 let details = &$crate::serde_json::Value::Null;
398 $(let details = $details;)?
399 let details = $crate::details::WithGuidance {
400 details,
401 guidance: || $crate::details::NumericOperands { left: &left, right: &right },
402 };
403 $assert!(left $op right, $message, &details);
404
405 let diff = $crate::assert::guidance::Diff::diff(&left, right);
407 static GUARD: $crate::assert::guidance::Guard<$maximize> =
408 $crate::assert::guidance::Guard::init();
409 if $crate::assert::guidance::finite_operands(&left, &right, $message)
410 && GUARD.should_emit(diff) {
411 let operands = $crate::details::NumericOperands { left: &left, right: &right };
412 if let Some(guidance_data) = $crate::details::guidance(&operands, $message) {
415 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Numeric, $message, $maximize, guidance_data);
416 }
417 }
418 }};
419}
420
421#[cfg(not(feature = "full"))]
422#[doc(hidden)]
423#[macro_export]
424macro_rules! numeric_guidance_helper {
425 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:expr$(, $details:expr)?) => {{
426 const _: &str = $message;
428 $assert!($left $op $right, $message$(, $details)?);
429 }};
430}
431
432#[cfg(feature = "full")]
433#[doc(hidden)]
434#[macro_export]
435macro_rules! boolean_guidance_helper {
436 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:expr$(, $details:expr)?) => {{
437 let details = &$crate::serde_json::Value::Null;
438 $(let details = $details;)?
439 let (cond, guidance_data) = {
440 $(let $name = $cond;)*
441 (
442 if $all { true $(&& $name)* } else { false $(|| $name)* },
443 $crate::serde_json::json!({$(::std::stringify!($name): $name),*})
444 )
445 };
446 let details = $crate::details::WithGuidance {
447 details,
448 guidance: || guidance_data.clone(),
449 };
450 $assert!(cond, $message, &details);
451 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Boolean, $message, $all, guidance_data);
454 }};
455}
456
457#[cfg(not(feature = "full"))]
458#[doc(hidden)]
459#[macro_export]
460macro_rules! boolean_guidance_helper {
461 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:expr$(, $details:expr)?) => {{
462 let cond = {
463 $(let $name = $cond;)*
464 if $all { true $(&& $name)* } else { false $(|| $name)* }
465 };
466 $assert!(cond, $message$(, $details)?);
467 }};
468}
469
470#[macro_export]
488macro_rules! assert_always_greater_than {
489 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
490 $crate::numeric_guidance_helper!($crate::assert_always, >, false, $left, $right, $message$(, $details)?)
491 };
492 ($($rest:tt)*) => {
493 ::std::compile_error!(
494r#"Invalid syntax when calling macro `assert_always_greater_than`.
495Example usage:
496 `assert_always_greater_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
497"#
498 );
499 };
500}
501
502#[macro_export]
507macro_rules! assert_always_greater_than_or_equal_to {
508 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
509 $crate::numeric_guidance_helper!($crate::assert_always, >=, false, $left, $right, $message$(, $details)?)
510 };
511 ($($rest:tt)*) => {
512 ::std::compile_error!(
513r#"Invalid syntax when calling macro `assert_always_greater_than_or_equal_to`.
514Example usage:
515 `assert_always_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
516"#
517 );
518 };
519}
520
521#[macro_export]
526macro_rules! assert_always_less_than {
527 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
528 $crate::numeric_guidance_helper!($crate::assert_always, <, true, $left, $right, $message$(, $details)?)
529 };
530 ($($rest:tt)*) => {
531 ::std::compile_error!(
532r#"Invalid syntax when calling macro `assert_always_less_than`.
533Example usage:
534 `assert_always_less_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
535"#
536 );
537 };
538}
539
540#[macro_export]
545macro_rules! assert_always_less_than_or_equal_to {
546 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
547 $crate::numeric_guidance_helper!($crate::assert_always, <=, true, $left, $right, $message$(, $details)?)
548 };
549 ($($rest:tt)*) => {
550 ::std::compile_error!(
551r#"Invalid syntax when calling macro `assert_always_less_than_or_equal_to`.
552Example usage:
553 `assert_always_less_than_or_equal_to!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
554"#
555 );
556 };
557}
558
559#[macro_export]
564macro_rules! assert_sometimes_greater_than {
565 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
566 $crate::numeric_guidance_helper!($crate::assert_sometimes, >, true, $left, $right, $message$(, $details)?)
567 };
568 ($($rest:tt)*) => {
569 ::std::compile_error!(
570r#"Invalid syntax when calling macro `assert_sometimes_greater_than`.
571Example usage:
572 `assert_sometimes_greater_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
573"#
574 );
575 };
576}
577
578#[macro_export]
583macro_rules! assert_sometimes_greater_than_or_equal_to {
584 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
585 $crate::numeric_guidance_helper!($crate::assert_sometimes, >=, true, $left, $right, $message$(, $details)?)
586 };
587 ($($rest:tt)*) => {
588 ::std::compile_error!(
589r#"Invalid syntax when calling macro `assert_sometimes_greater_than_or_equal_to`.
590Example usage:
591 `assert_sometimes_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
592"#
593 );
594 };
595}
596
597#[macro_export]
602macro_rules! assert_sometimes_less_than {
603 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
604 $crate::numeric_guidance_helper!($crate::assert_sometimes, <, false, $left, $right, $message$(, $details)?)
605 };
606 ($($rest:tt)*) => {
607 ::std::compile_error!(
608r#"Invalid syntax when calling macro `assert_sometimes_less_than`.
609Example usage:
610 `assert_sometimes_less_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
611"#
612 );
613 };
614}
615
616#[macro_export]
621macro_rules! assert_sometimes_less_than_or_equal_to {
622 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
623 $crate::numeric_guidance_helper!($crate::assert_sometimes, <=, false, $left, $right, $message$(, $details)?)
624 };
625 ($($rest:tt)*) => {
626 ::std::compile_error!(
627r#"Invalid syntax when calling macro `assert_sometimes_less_than_or_equal_to`.
628Example usage:
629 `assert_sometimes_less_than_or_equal_to!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
630"#
631 );
632 };
633}
634
635#[macro_export]
654macro_rules! assert_always_some {
655 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:expr$(, $details:expr)?) => {
656 $crate::boolean_guidance_helper!($crate::assert_always, false, {$($($name: $cond),+)?}, $message$(, $details)?);
657 };
658 ($($rest:tt)*) => {
659 ::std::compile_error!(
660r#"Invalid syntax when calling macro `assert_always_some`.
661Example usage:
662 `assert_always_some!({field1: cond1, field2: cond2, ...}, "assertion message (const &'static str)", &details_json_value_expr)`
663"#
664 );
665 };
666}
667
668#[macro_export]
674macro_rules! assert_sometimes_all {
675 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:expr$(, $details:expr)?) => {
676 $crate::boolean_guidance_helper!($crate::assert_sometimes, true, {$($($name: $cond),+)?}, $message$(, $details)?);
677 };
678 ($($rest:tt)*) => {
679 ::std::compile_error!(
680r#"Invalid syntax when calling macro `assert_sometimes_all`.
681Example usage:
682 `assert_sometimes_all!({field1: cond1, field2: cond2, ...}, "assertion message (const &'static str)", &details_json_value_expr)`
683"#
684 );
685 };
686}