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::json!({});
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]
142macro_rules! assert_always {
143 ($condition:expr, $message:expr$(, $details:expr)?) => {
144 $crate::assert_helper!(
145 condition = $condition,
146 $message,
147 $(details = $details)?,
148 $crate::assert::AssertType::Always,
149 "Always",
150 must_hit = true
151 )
152 };
153 ($($rest:tt)*) => {
154 ::std::compile_error!(
155r#"Invalid syntax when calling macro `assert_always`.
156Example usage:
157 `assert_always!(condition_expr, "assertion message (const &'static str)", &details_json_value_expr)`
158"#
159 );
160 };
161}
162
163#[macro_export]
178macro_rules! assert_always_or_unreachable {
179 ($condition:expr, $message:expr$(, $details:expr)?) => {
180 $crate::assert_helper!(
181 condition = $condition,
182 $message,
183 $(details = $details)?,
184 $crate::assert::AssertType::Always,
185 "AlwaysOrUnreachable",
186 must_hit = false
187 )
188 };
189 ($($rest:tt)*) => {
190 ::std::compile_error!(
191r#"Invalid syntax when calling macro `assert_always_or_unreachable`.
192Example usage:
193 `assert_always_or_unreachable!(condition_expr, "assertion message (const &'static str)", &details_json_value_expr)`
194"#
195 );
196 };
197}
198
199#[macro_export]
215macro_rules! assert_sometimes {
216 ($condition:expr, $message:expr$(, $details:expr)?) => {
217 $crate::assert_helper!(
218 condition = $condition,
219 $message,
220 $(details = $details)?,
221 $crate::assert::AssertType::Sometimes,
222 "Sometimes",
223 must_hit = true
224 )
225 };
226 ($($rest:tt)*) => {
227 ::std::compile_error!(
228r#"Invalid syntax when calling macro `assert_sometimes`.
229Example usage:
230 `assert_sometimes!(condition_expr, "assertion message (const &'static str)", &details_json_value_expr)`
231"#
232 );
233 };
234}
235
236#[macro_export]
254macro_rules! assert_reachable {
255 ($message:expr$(, $details:expr)?) => {
256 $crate::assert_helper!(
257 condition = true,
258 $message,
259 $(details = $details)?,
260 $crate::assert::AssertType::Reachability,
261 "Reachable",
262 must_hit = true
263 )
264 };
265 ($($rest:tt)*) => {
266 ::std::compile_error!(
267r#"Invalid syntax when calling macro `assert_reachable`.
268Example usage:
269 `assert_reachable!("assertion message (const &'static str)", &details_json_value_expr)`
270"#
271 );
272 };
273}
274
275#[macro_export]
294macro_rules! assert_unreachable {
295 ($message:expr$(, $details:expr)?) => {
296 $crate::assert_helper!(
297 condition = false,
298 $message,
299 $(details = $details)?,
300 $crate::assert::AssertType::Reachability,
301 "Unreachable",
302 must_hit = false
303 )
304 };
305 ($($rest:tt)*) => {
306 ::std::compile_error!(
307r#"Invalid syntax when calling macro `assert_unreachable`.
308Example usage:
309 `assert_unreachable!("assertion message (const &'static str)", &details_json_value_expr)`
310"#
311 );
312 };
313}
314
315#[cfg(feature = "full")]
316#[doc(hidden)]
317#[macro_export]
318macro_rules! guidance_helper {
319 ($guidance_type:expr, $message:expr, $maximize:literal, $guidance_data:expr) => {
320 const _: &str = $message;
322
323 $crate::function!(FUN_NAME);
324
325 use $crate::assert::guidance::{GuidanceCatalogInfo, GuidanceType};
326 #[$crate::linkme::distributed_slice($crate::assert::ANTITHESIS_GUIDANCE_CATALOG)]
327 #[linkme(crate = $crate::linkme)] static GUIDANCE_CATALOG_ITEM: GuidanceCatalogInfo = GuidanceCatalogInfo {
329 guidance_type: $guidance_type,
330 message: $message,
331 id: $message,
332 class: ::std::module_path!(),
333 function: &FUN_NAME,
334 file: ::std::file!(),
335 begin_line: ::std::line!(),
336 begin_column: ::std::column!(),
337 maximize: $maximize,
338 };
339
340 $crate::assert::guidance::guidance_impl(
341 $guidance_type,
342 $message,
343 $message,
344 ::std::module_path!(),
345 *Lazy::force(&FUN_NAME),
346 ::std::file!(),
347 ::std::line!(),
348 ::std::column!(),
349 $maximize,
350 $guidance_data,
351 true,
352 )
353 };
354}
355
356#[cfg(feature = "full")]
357#[doc(hidden)]
358#[macro_export]
359macro_rules! numeric_guidance_helper {
360 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:expr$(, $details:expr)?) => {{
361 let left = $left;
362 let right = $right;
363 let details = &$crate::serde_json::json!({});
364 $(let details = $details;)?
365 let mut details = details.clone();
366 details["left"] = left.into();
367 details["right"] = right.into();
368 $assert!(left $op right, $message, &details);
369
370 let guidance_data = $crate::serde_json::json!({
371 "left": left,
372 "right": right,
373 });
374 let diff = $crate::assert::guidance::Diff::diff(&left, right);
388 type Guard<T> = $crate::assert::guidance::Guard<$maximize, T>;
389 type Distance = f64;
392 static GUARD: Guard<Distance> = Guard::init();
393 if GUARD.should_emit(diff) {
394 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Numeric, $message, $maximize, guidance_data);
395 }
396 }};
397}
398
399#[cfg(not(feature = "full"))]
400#[doc(hidden)]
401#[macro_export]
402macro_rules! numeric_guidance_helper {
403 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:expr$(, $details:expr)?) => {{
404 const _: &str = $message;
406 $assert!($left $op $right, $message$(, $details)?);
407 }};
408}
409
410#[cfg(feature = "full")]
411#[doc(hidden)]
412#[macro_export]
413macro_rules! boolean_guidance_helper {
414 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:expr$(, $details:expr)?) => {{
415 let details = &$crate::serde_json::json!({});
416 $(let details = $details;)?
417 let mut details = details.clone();
418 let (cond, guidance_data) = {
419 $(let $name = $cond;)*
420 $(details[::std::stringify!($name)] = $name.into();)*
421 (
422 if $all { true $(&& $name)* } else { false $(|| $name)* },
423 $crate::serde_json::json!({$(::std::stringify!($name): $name),*})
424 )
425 };
426 $assert!(cond, $message, &details);
427 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Boolean, $message, $all, guidance_data);
428 }};
429}
430
431#[cfg(not(feature = "full"))]
432#[doc(hidden)]
433#[macro_export]
434macro_rules! boolean_guidance_helper {
435 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:expr$(, $details:expr)?) => {{
436 let cond = {
437 $(let $name = $cond;)*
438 if $all { true $(&& $name)* } else { false $(|| $name)* }
439 };
440 $assert!(cond, $message$(, $details)?);
441 }};
442}
443
444#[macro_export]
459macro_rules! assert_always_greater_than {
460 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
461 $crate::numeric_guidance_helper!($crate::assert_always, >, false, $left, $right, $message$(, $details)?)
462 };
463 ($($rest:tt)*) => {
464 ::std::compile_error!(
465r#"Invalid syntax when calling macro `assert_always_greater_than`.
466Example usage:
467 `assert_always_greater_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
468"#
469 );
470 };
471}
472
473#[macro_export]
475macro_rules! assert_always_greater_than_or_equal_to {
476 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
477 $crate::numeric_guidance_helper!($crate::assert_always, >=, false, $left, $right, $message$(, $details)?)
478 };
479 ($($rest:tt)*) => {
480 ::std::compile_error!(
481r#"Invalid syntax when calling macro `assert_always_greater_than_or_equal_to`.
482Example usage:
483 `assert_always_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
484"#
485 );
486 };
487}
488
489#[macro_export]
491macro_rules! assert_always_less_than {
492 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
493 $crate::numeric_guidance_helper!($crate::assert_always, <, true, $left, $right, $message$(, $details)?)
494 };
495 ($($rest:tt)*) => {
496 ::std::compile_error!(
497r#"Invalid syntax when calling macro `assert_always_less_than`.
498Example usage:
499 `assert_always_less_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
500"#
501 );
502 };
503}
504
505#[macro_export]
507macro_rules! assert_always_less_than_or_equal_to {
508 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
509 $crate::numeric_guidance_helper!($crate::assert_always, <=, true, $left, $right, $message$(, $details)?)
510 };
511 ($($rest:tt)*) => {
512 ::std::compile_error!(
513r#"Invalid syntax when calling macro `assert_always_less_than_or_equal_to`.
514Example usage:
515 `assert_always_less_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]
523macro_rules! assert_sometimes_greater_than {
524 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
525 $crate::numeric_guidance_helper!($crate::assert_sometimes, >, true, $left, $right, $message$(, $details)?)
526 };
527 ($($rest:tt)*) => {
528 ::std::compile_error!(
529r#"Invalid syntax when calling macro `assert_sometimes_greater_than`.
530Example usage:
531 `assert_sometimes_greater_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
532"#
533 );
534 };
535}
536
537#[macro_export]
539macro_rules! assert_sometimes_greater_than_or_equal_to {
540 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
541 $crate::numeric_guidance_helper!($crate::assert_sometimes, >=, true, $left, $right, $message$(, $details)?)
542 };
543 ($($rest:tt)*) => {
544 ::std::compile_error!(
545r#"Invalid syntax when calling macro `assert_sometimes_greater_than_or_equal_to`.
546Example usage:
547 `assert_sometimes_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
548"#
549 );
550 };
551}
552
553#[macro_export]
555macro_rules! assert_sometimes_less_than {
556 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
557 $crate::numeric_guidance_helper!($crate::assert_sometimes, <, false, $left, $right, $message$(, $details)?)
558 };
559 ($($rest:tt)*) => {
560 ::std::compile_error!(
561r#"Invalid syntax when calling macro `assert_sometimes_less_than`.
562Example usage:
563 `assert_sometimes_less_than!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
564"#
565 );
566 };
567}
568
569#[macro_export]
571macro_rules! assert_sometimes_less_than_or_equal_to {
572 ($left:expr, $right:expr, $message:expr$(, $details:expr)?) => {
573 $crate::numeric_guidance_helper!($crate::assert_sometimes, <=, false, $left, $right, $message$(, $details)?)
574 };
575 ($($rest:tt)*) => {
576 ::std::compile_error!(
577r#"Invalid syntax when calling macro `assert_sometimes_less_than_or_equal_to`.
578Example usage:
579 `assert_sometimes_less_than_or_equal_to!(left_expr, right_expr, "assertion message (const &'static str)", &details_json_value_expr)`
580"#
581 );
582 };
583}
584
585#[macro_export]
603macro_rules! assert_always_some {
604 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:expr$(, $details:expr)?) => {
605 $crate::boolean_guidance_helper!($crate::assert_always, false, {$($($name: $cond),+)?}, $message$(, $details)?);
606 };
607 ($($rest:tt)*) => {
608 ::std::compile_error!(
609r#"Invalid syntax when calling macro `assert_always_some`.
610Example usage:
611 `assert_always_some!({field1: cond1, field2: cond2, ...}, "assertion message (const &'static str)", &details_json_value_expr)`
612"#
613 );
614 };
615}
616
617#[macro_export]
622macro_rules! assert_sometimes_all {
623 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:expr$(, $details:expr)?) => {
624 $crate::boolean_guidance_helper!($crate::assert_sometimes, true, {$($($name: $cond),+)?}, $message$(, $details)?);
625 };
626 ($($rest:tt)*) => {
627 ::std::compile_error!(
628r#"Invalid syntax when calling macro `assert_sometimes_all`.
629Example usage:
630 `assert_sometimes_all!({field1: cond1, field2: cond2, ...}, "assertion message (const &'static str)", &details_json_value_expr)`
631"#
632 );
633 };
634}