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