risingwave_error/
macros.rs1#[macro_export]
53macro_rules! ensure {
54 ($cond:expr $(,)?) => {
55 if !$cond {
56 return Err(::anyhow::anyhow!(stringify!($cond)).into());
57 }
58 };
59 ($cond:expr, $msg:literal $(,)?) => {
60 if !$cond {
61 return Err(::anyhow::anyhow!($msg).into());
62 }
63 };
64 ($cond:expr, $fmt:expr, $($arg:tt)*) => {
65 if !$cond {
66 return Err(::anyhow::anyhow!($fmt, $($arg)*).into());
67 }
68 };
69 ($cond:expr, $error_code:expr) => {
70 if !$cond {
71 return Err($error_code.into());
72 }
73 };
74}
75pub use ensure;
76
77#[macro_export]
79macro_rules! ensure_eq {
80 ($left:expr, $right:expr) => {
81 match (&$left, &$right) {
82 (left_val, right_val) => {
83 if !(left_val == right_val) {
84 $crate::bail!(
85 "{} == {} assertion failed ({} is {}, {} is {})",
86 stringify!($left),
87 stringify!($right),
88 stringify!($left),
89 &*left_val,
90 stringify!($right),
91 &*right_val,
92 );
93 }
94 }
95 }
96 };
97}
98pub use ensure_eq;
99
100#[macro_export]
105macro_rules! bail {
106 ($($arg:tt)*) => {
107 return Err(::anyhow::anyhow!($($arg)*).into())
108 };
109}
110pub use bail;
111
112#[macro_export]
116macro_rules! try_match_expand {
117 ($e:expr, $variant:path) => {
118 match $e {
119 $variant(internal) => Ok(internal),
120 _ => Err(::anyhow::anyhow!(
121 "unable to match {} with {}",
122 stringify!($e),
123 stringify!($variant),
124 )),
125 }
126 };
127 ($e:expr, $variant:path, $($arg:tt)+) => {
128 match $e {
129 $variant(internal) => Ok(internal),
130 _ => Err(::anyhow::anyhow!($($arg)+)),
131 }
132 };
133}
134pub use try_match_expand;
135
136#[macro_export]
140macro_rules! must_match {
141 ($expression:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $action:expr) => {
142 match $expression {
143 $( $pattern )|+ $( if $guard )? => $action,
144 _ => panic!("enum variant mismatch: `{}` is required", stringify!($( $pattern )|+ $( if $guard )?)),
145 }
146 };
147}
148pub use must_match;
149
150#[cfg(test)]
151mod ensure_tests {
152 use anyhow::anyhow;
153 use thiserror::Error;
154
155 #[derive(Error, Debug)]
156 #[error(transparent)]
157 struct MyError(#[from] anyhow::Error);
158
159 #[test]
160 fn test_ensure() {
161 let a = 1;
162
163 {
164 let err_msg = "a < 0";
165 let error = (|| {
166 ensure!(a < 0);
167 Ok::<_, MyError>(())
168 })()
169 .unwrap_err();
170
171 assert_eq!(MyError(anyhow!(err_msg)).to_string(), error.to_string(),);
172 }
173
174 {
175 let err_msg = "error msg without args";
176 let error = (|| {
177 ensure!(a < 0, "error msg without args");
178 Ok::<_, MyError>(())
179 })()
180 .unwrap_err();
181 assert_eq!(MyError(anyhow!(err_msg)).to_string(), error.to_string());
182 }
183
184 {
185 let error = (|| {
186 ensure!(a < 0, "error msg with args: {}", "xx");
187 Ok::<_, MyError>(())
188 })()
189 .unwrap_err();
190 assert_eq!(
191 MyError(anyhow!("error msg with args: {}", "xx")).to_string(),
192 error.to_string()
193 );
194 }
195 }
196
197 #[test]
198 fn test_ensure_eq() {
199 fn ensure_a_equals_b() -> Result<(), MyError> {
200 let a = 1;
201 let b = 2;
202 ensure_eq!(a, b);
203 Ok(())
204 }
205 let err = ensure_a_equals_b().unwrap_err();
206 assert_eq!(err.to_string(), "a == b assertion failed (a is 1, b is 2)");
207 }
208}
209
210#[cfg(test)]
211mod match_tests {
212 #[derive(thiserror::Error, Debug)]
213 #[error(transparent)]
214 struct ExpandError(#[from] anyhow::Error);
215
216 #[allow(dead_code)]
217 enum MyEnum {
218 A(String),
219 B,
220 }
221
222 #[test]
223 fn test_try_match() -> Result<(), ExpandError> {
224 assert_eq!(
225 try_match_expand!(MyEnum::A("failure".to_owned()), MyEnum::A)?,
226 "failure"
227 );
228 assert_eq!(
229 try_match_expand!(MyEnum::A("failure".to_owned()), MyEnum::A)?,
230 "failure"
231 );
232 assert_eq!(
233 try_match_expand!(MyEnum::A("failure".to_owned()), MyEnum::A)?,
234 "failure"
235 );
236
237 let err_str = try_match_expand!(MyEnum::A("failure".to_owned()), MyEnum::A)?;
239 assert_eq!(err_str, "failure");
240 Ok(())
241 }
242
243 #[test]
244 fn test_must_match() -> Result<(), ExpandError> {
245 #[allow(dead_code)]
246 enum A {
247 Foo,
248 Bar,
249 }
250 let a = A::Foo;
251 let val = must_match!(a, A::Foo => 42);
252 assert_eq!(val, 42);
253
254 #[allow(dead_code)]
255 enum B {
256 Foo,
257 Bar(i32),
258 Baz { x: u32, y: u32 },
259 }
260 let b = B::Baz { x: 1, y: 2 };
261 let val = must_match!(b, B::Baz { x, y } if x == 1 => x + y);
262 assert_eq!(val, 3);
263 let b = B::Bar(42);
264 let val = must_match!(b, B::Bar(x) => {
265 let y = x + 1;
266 y * 2
267 });
268 assert_eq!(val, 86);
269
270 Ok(())
271 }
272}