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 static TRACKER: $crate::assert::TrackingInfo = $crate::assert::TrackingInfo::new();
66
67 $crate::assert::assert_impl(
68 $assert_type, $display_type, condition, $message, ::std::module_path!(), *ptr_function, ::std::file!(), ::std::line!(), ::std::column!(), true, $must_hit, $message, details, Some(&TRACKER), )
83 }}; }
85
86#[cfg(not(feature = "full"))]
87#[doc(hidden)]
88#[macro_export]
89macro_rules! assert_helper {
90 (condition = $condition:expr, $message:literal, $(details = $details:expr)?, $assert_type:path, $display_type:literal, must_hit = $must_hit:literal) => {{
91 let condition = $condition;
96 $(let details = $details;)?
97 }};
98}
99
100#[macro_export]
115macro_rules! assert_always {
116 ($condition:expr, $message:literal$(, $details:expr)?) => {
117 $crate::assert_helper!(
118 condition = $condition,
119 $message,
120 $(details = $details)?,
121 $crate::assert::AssertType::Always,
122 "Always",
123 must_hit = true
124 )
125 };
126 ($($rest:tt)*) => {
127 ::std::compile_error!(
128r#"Invalid syntax when calling macro `assert_always`.
129Example usage:
130 `assert_always!(condition_expr, "assertion message (static literal)", &details_json_value_expr)`
131"#
132 );
133 };
134}
135
136#[macro_export]
151macro_rules! assert_always_or_unreachable {
152 ($condition:expr, $message:literal$(, $details:expr)?) => {
153 $crate::assert_helper!(
154 condition = $condition,
155 $message,
156 $(details = $details)?,
157 $crate::assert::AssertType::Always,
158 "AlwaysOrUnreachable",
159 must_hit = false
160 )
161 };
162 ($($rest:tt)*) => {
163 ::std::compile_error!(
164r#"Invalid syntax when calling macro `assert_always_or_unreachable`.
165Example usage:
166 `assert_always_or_unreachable!(condition_expr, "assertion message (static literal)", &details_json_value_expr)`
167"#
168 );
169 };
170}
171
172#[macro_export]
188macro_rules! assert_sometimes {
189 ($condition:expr, $message:literal$(, $details:expr)?) => {
190 $crate::assert_helper!(
191 condition = $condition,
192 $message,
193 $(details = $details)?,
194 $crate::assert::AssertType::Sometimes,
195 "Sometimes",
196 must_hit = true
197 )
198 };
199 ($($rest:tt)*) => {
200 ::std::compile_error!(
201r#"Invalid syntax when calling macro `assert_sometimes`.
202Example usage:
203 `assert_sometimes!(condition_expr, "assertion message (static literal)", &details_json_value_expr)`
204"#
205 );
206 };
207}
208
209#[macro_export]
227macro_rules! assert_reachable {
228 ($message:literal$(, $details:expr)?) => {
229 $crate::assert_helper!(
230 condition = true,
231 $message,
232 $(details = $details)?,
233 $crate::assert::AssertType::Reachability,
234 "Reachable",
235 must_hit = true
236 )
237 };
238 ($($rest:tt)*) => {
239 ::std::compile_error!(
240r#"Invalid syntax when calling macro `assert_reachable`.
241Example usage:
242 `assert_reachable!("assertion message (static literal)", &details_json_value_expr)`
243"#
244 );
245 };
246}
247
248#[macro_export]
267macro_rules! assert_unreachable {
268 ($message:literal$(, $details:expr)?) => {
269 $crate::assert_helper!(
270 condition = false,
271 $message,
272 $(details = $details)?,
273 $crate::assert::AssertType::Reachability,
274 "Unreachable",
275 must_hit = false
276 )
277 };
278 ($($rest:tt)*) => {
279 ::std::compile_error!(
280r#"Invalid syntax when calling macro `assert_unreachable`.
281Example usage:
282 `assert_unreachable!("assertion message (static literal)", &details_json_value_expr)`
283"#
284 );
285 };
286}
287
288#[cfg(feature = "full")]
289#[doc(hidden)]
290#[macro_export]
291macro_rules! guidance_helper {
292 ($guidance_type:expr, $message:literal, $maximize:literal, $guidance_data:expr) => {
293 $crate::function!(FUN_NAME);
294
295 use $crate::assert::guidance::{GuidanceCatalogInfo, GuidanceType};
296 #[$crate::linkme::distributed_slice($crate::assert::ANTITHESIS_GUIDANCE_CATALOG)]
297 #[linkme(crate = $crate::linkme)] static GUIDANCE_CATALOG_ITEM: GuidanceCatalogInfo = GuidanceCatalogInfo {
299 guidance_type: $guidance_type,
300 message: $message,
301 id: $message,
302 class: ::std::module_path!(),
303 function: &FUN_NAME,
304 file: ::std::file!(),
305 begin_line: ::std::line!(),
306 begin_column: ::std::column!(),
307 maximize: $maximize,
308 };
309
310 $crate::assert::guidance::guidance_impl(
311 $guidance_type,
312 $message,
313 $message,
314 ::std::module_path!(),
315 *Lazy::force(&FUN_NAME),
316 ::std::file!(),
317 ::std::line!(),
318 ::std::column!(),
319 $maximize,
320 $guidance_data,
321 true,
322 )
323 };
324}
325
326#[cfg(feature = "full")]
327#[doc(hidden)]
328#[macro_export]
329macro_rules! numeric_guidance_helper {
330 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:literal$(, $details:expr)?) => {{
331 let left = $left;
332 let right = $right;
333 let details = &$crate::serde_json::json!({});
334 $(let details = $details;)?
335 let mut details = details.clone();
336 details["left"] = left.into();
337 details["right"] = right.into();
338 $assert!(left $op right, $message, &details);
339
340 let guidance_data = $crate::serde_json::json!({
341 "left": left,
342 "right": right,
343 });
344 let diff = $crate::assert::guidance::Diff::diff(&left, right);
358 type Guard<T> = $crate::assert::guidance::Guard<$maximize, T>;
359 type Distance = f64;
362 static GUARD: Guard<Distance> = Guard::init();
363 if GUARD.should_emit(diff) {
364 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Numeric, $message, $maximize, guidance_data);
365 }
366 }};
367}
368
369#[cfg(not(feature = "full"))]
370#[doc(hidden)]
371#[macro_export]
372macro_rules! numeric_guidance_helper {
373 ($assert:path, $op:tt, $maximize:literal, $left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
374 assert!($left $op $right, $message$(, $details)?);
375 };
376}
377
378#[cfg(feature = "full")]
379#[doc(hidden)]
380#[macro_export]
381macro_rules! boolean_guidance_helper {
382 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:literal$(, $details:expr)?) => {{
383 let details = &$crate::serde_json::json!({});
384 $(let details = $details;)?
385 let mut details = details.clone();
386 let (cond, guidance_data) = {
387 $(let $name = $cond;)*
388 $(details[::std::stringify!($name)] = $name.into();)*
389 (
390 if $all { true $(&& $name)* } else { false $(|| $name)* },
391 $crate::serde_json::json!({$(::std::stringify!($name): $name),*})
392 )
393 };
394 $assert!(cond, $message, &details);
395 $crate::guidance_helper!($crate::assert::guidance::GuidanceType::Boolean, $message, $all, guidance_data);
396 }};
397}
398
399#[cfg(not(feature = "full"))]
400#[doc(hidden)]
401#[macro_export]
402macro_rules! boolean_guidance_helper {
403 ($assert:path, $all:literal, {$($name:ident: $cond:expr),*}, $message:literal$(, $details:expr)?) => {{
404 let cond = {
405 $(let $name = $cond;)*
406 if $all { true $(&& $name)* } else { false $(|| $name)* }
407 };
408 $assert!(cond, $message$(, $details)?);
409 }};
410}
411
412#[macro_export]
414macro_rules! assert_always_greater_than {
415 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
416 $crate::numeric_guidance_helper!($crate::assert_always, >, false, $left, $right, $message$(, $details)?)
417 };
418 ($($rest:tt)*) => {
419 ::std::compile_error!(
420r#"Invalid syntax when calling macro `assert_always_greater_than`.
421Example usage:
422 `assert_always_greater_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
423"#
424 );
425 };
426}
427
428#[macro_export]
430macro_rules! assert_always_greater_than_or_equal_to {
431 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
432 $crate::numeric_guidance_helper!($crate::assert_always, >=, false, $left, $right, $message$(, $details)?)
433 };
434 ($($rest:tt)*) => {
435 ::std::compile_error!(
436r#"Invalid syntax when calling macro `assert_always_greater_than_or_equal_to`.
437Example usage:
438 `assert_always_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
439"#
440 );
441 };
442}
443
444#[macro_export]
446macro_rules! assert_always_less_than {
447 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
448 $crate::numeric_guidance_helper!($crate::assert_always, <, true, $left, $right, $message$(, $details)?)
449 };
450 ($($rest:tt)*) => {
451 ::std::compile_error!(
452r#"Invalid syntax when calling macro `assert_always_less_than`.
453Example usage:
454 `assert_always_less_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
455"#
456 );
457 };
458}
459
460#[macro_export]
462macro_rules! assert_always_less_than_or_equal_to {
463 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
464 $crate::numeric_guidance_helper!($crate::assert_always, <=, true, $left, $right, $message$(, $details)?)
465 };
466 ($($rest:tt)*) => {
467 ::std::compile_error!(
468r#"Invalid syntax when calling macro `assert_always_less_than_or_equal_to`.
469Example usage:
470 `assert_always_less_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
471"#
472 );
473 };
474}
475
476#[macro_export]
478macro_rules! assert_sometimes_greater_than {
479 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
480 $crate::numeric_guidance_helper!($crate::assert_sometimes, >, true, $left, $right, $message$(, $details)?)
481 };
482 ($($rest:tt)*) => {
483 ::std::compile_error!(
484r#"Invalid syntax when calling macro `assert_sometimes_greater_than`.
485Example usage:
486 `assert_sometimes_greater_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
487"#
488 );
489 };
490}
491
492#[macro_export]
494macro_rules! assert_sometimes_greater_than_or_equal_to {
495 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
496 $crate::numeric_guidance_helper!($crate::assert_sometimes, >=, true, $left, $right, $message$(, $details)?)
497 };
498 ($($rest:tt)*) => {
499 ::std::compile_error!(
500r#"Invalid syntax when calling macro `assert_sometimes_greater_than_or_equal_to`.
501Example usage:
502 `assert_sometimes_greater_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
503"#
504 );
505 };
506}
507
508#[macro_export]
510macro_rules! assert_sometimes_less_than {
511 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
512 $crate::numeric_guidance_helper!($crate::assert_sometimes, <, false, $left, $right, $message$(, $details)?)
513 };
514 ($($rest:tt)*) => {
515 ::std::compile_error!(
516r#"Invalid syntax when calling macro `assert_sometimes_less_than`.
517Example usage:
518 `assert_sometimes_less_than!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
519"#
520 );
521 };
522}
523
524#[macro_export]
526macro_rules! assert_sometimes_less_than_or_equal_to {
527 ($left:expr, $right:expr, $message:literal$(, $details:expr)?) => {
528 $crate::numeric_guidance_helper!($crate::assert_sometimes, <=, false, $left, $right, $message$(, $details)?)
529 };
530 ($($rest:tt)*) => {
531 ::std::compile_error!(
532r#"Invalid syntax when calling macro `assert_sometimes_less_than_or_equal_to`.
533Example usage:
534 `assert_sometimes_less_than_or_equal_to!(left_expr, right_expr, "assertion message (static literal)", &details_json_value_expr)`
535"#
536 );
537 };
538}
539
540#[macro_export]
545macro_rules! assert_always_some {
546 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:literal$(, $details:expr)?) => {
547 $crate::boolean_guidance_helper!($crate::assert_always, false, {$($($name: $cond),+)?}, $message$(, $details)?);
548 };
549 ($($rest:tt)*) => {
550 ::std::compile_error!(
551r#"Invalid syntax when calling macro `assert_always_some`.
552Example usage:
553 `assert_always_some!({field1: cond1, field2: cond2, ...}, "assertion message (static literal)", &details_json_value_expr)`
554"#
555 );
556 };
557}
558
559#[macro_export]
564macro_rules! assert_sometimes_all {
565 ({$($($name:ident: $cond:expr),+ $(,)?)?}, $message:literal$(, $details:expr)?) => {
566 $crate::boolean_guidance_helper!($crate::assert_sometimes, true, {$($($name: $cond),+)?}, $message$(, $details)?);
567 };
568 ($($rest:tt)*) => {
569 ::std::compile_error!(
570r#"Invalid syntax when calling macro `assert_sometimes_all`.
571Example usage:
572 `assert_sometimes_all!({field1: cond1, field2: cond2, ...}, "assertion message (static literal)", &details_json_value_expr)`
573"#
574 );
575 };
576}