1use std::fmt::Display;
2
3#[macro_export]
13macro_rules! bug {
14 ($msg:expr)=> {
15 $crate::bug!($msg,)
16 };
17
18 ($msg:expr, $($arg:tt)*) => {{
19 let formatted_msg = format!($msg, $($arg)*);
20 let full_message = format!(
21 r#"
22This should never happen, sorry!
23
24However, it did happen, so it must be a bug. Please report it to us!
25
26Conjure Oxide is actively developed and maintained. We will get back to you as soon as possible.
27
28You can help us by providing a minimal failing example.
29
30Issue tracker: http://github.com/conjure-cp/conjure-oxide/issues
31
32version: {}
33location: {}:{}:{}
34
35{}
36"#, git_version::git_version!(),file!(),module_path!(),line!(), &formatted_msg);
37
38 panic!("{}", full_message);
39 }};
40}
41
42#[macro_export]
44macro_rules! bug_assert {
45 ($cond:expr, $msg:expr, $($arg:tt)*) => {
46 if !$cond {
47 let formatted_msg = format!($msg, $($arg)*);
48 $crate::bug!("assertion failed: {}\n{}", stringify!($cond), formatted_msg);
49 }
50 };
51
52 ($cond:expr, $msg:expr) => {
53 if !$cond {
54 $crate::bug!("assertion failed: {}\n{}", stringify!($cond), $msg);
55 }
56 };
57
58 ($cond:expr) => {
59 if !$cond {
60 $crate::bug!("assertion failed: {}", stringify!($cond));
61 }
62 };
63}
64
65#[macro_export]
67macro_rules! bug_assert_eq {
68 ($left:expr, $right:expr, $msg:expr, $($arg:tt)*) => {
69 if &$left != &$right {
70 let formatted_msg = format!($msg, $($arg)*);
71 $crate::bug!(
72 "assertion failed: {} != {}\n{}",
73 stringify!($left),
74 stringify!($right),
75 formatted_msg
76 );
77 }
78 };
79
80 ($left:expr, $right:expr, $msg:expr) => {
81 $crate::bug_assert_eq!($left, $right, $msg,);
82 };
83
84 ($left:expr, $right:expr) => {
85 if &$left != &$right {
86 $crate::bug!(
87 "assertion failed: {} != {}",
88 stringify!($left),
89 stringify!($right)
90 );
91 }
92 };
93}
94
95pub trait UnwrapOrBug {
96 type Output;
97 fn unwrap_or_bug(self) -> Self::Output;
98}
99
100impl<T, E: Display> UnwrapOrBug for Result<T, E> {
101 type Output = T;
102 fn unwrap_or_bug(self) -> Self::Output {
103 self.unwrap_or_else(|e| bug!("error: {}", e))
104 }
105}
106
107impl<T> UnwrapOrBug for Option<T> {
108 type Output = T;
109 fn unwrap_or_bug(self) -> Self::Output {
110 self.unwrap_or_else(|| bug!("expected a value, but got None"))
111 }
112}