devela/code/result/opt_res/
unwrap.rs

1// devela::code::result::opt_res::unwrap
2//
3//!
4//
5
6/// An unwrapper macro that works in compile-time.
7///
8/// It supports unwrapping [`Option`], [`Result`] and [`OptRes`][super::OptRes].
9#[macro_export]
10#[cfg_attr(cargo_primary_package, doc(hidden))]
11macro_rules! unwrap {
12    (
13
14      // Option<T>
15      // ---------
16
17      // Unwraps the contained `Some` value, or otherwise returns `None`.
18      some? $value:expr ) => {
19        match $value {
20            Some(v) => v,
21            None => return None,
22        }
23    };
24    (
25      // Unwraps the contained `Some` value, or panics if it's `None`.
26      some $value:expr) => {
27        match $value {
28            Some(v) => v,
29            None => core::panic![],
30        }
31    };
32    (
33      // Unwraps the contained `Some` value, or panics with the given message if it's `None`.
34      some_expect $value:expr, $message:literal) => {
35        match $value {
36            Some(v) => v,
37            None => core::panic!["{}", $message],
38        }
39    };
40    (
41      // Unwraps the contained `Some` value, or the given default if it's `None`.
42      some_or $value:expr, $default:expr) => {
43        match $value {
44            Some(v) => v,
45            None => $default,
46        }
47    };
48    (
49      // Transforms the `Option` into a `Result`, mapping `Some(T)` to `Ok(T)`,
50      // and `None` to `Err($err)`.
51      some_ok_or $value:expr, $err:expr) => {
52        match $value {
53            Some(v) => Ok(v),
54            None => Err($err),
55        }
56    };
57    (
58      // Unwraps the contained `Some` value or otherwise returns Err($err).
59      some_ok_or? $value:expr, $err:expr) => {
60        match $value {
61            Some(v) => v,
62            None => return Err($err),
63        }
64    };
65    (
66
67      // Result<T, E>
68      // ------------
69
70      // Unwraps the contained `Ok` value, or otherwise returns the `Err` value.
71      ok? $value:expr ) => {
72        match $value {
73            Ok(v) => v,
74            Err(e) => return Err(e),
75        }
76    };
77    (
78      // Unwraps the contained `Ok` value, or panics if it's `Err`.
79      ok $value:expr ) => {
80        match $value {
81            Ok(v) => v,
82            Err(_) => core::panic![],
83        }
84    };
85    (
86      // Unwraps the contained `Ok` value, or panics with the given message if it's `Err`.
87      ok_expect $value:expr, $message:literal) => {
88        match $value {
89            Ok(v) => v,
90            Err(_) => core::panic!["{}", $message],
91        }
92    };
93    (
94      // Unwraps the contained `Ok` value, or a provided default if it's `Err`.
95      ok_or $value:expr, $default:expr) => {
96        match $value {
97            Ok(v) => v,
98            Err(_) => $default,
99        }
100    };
101    (
102      // Transforms the `Result` into an `Option`, mapping `Ok(T)` to `Some(T)`,
103      // and `Err(_)` to `None`.
104      ok_some $value:expr) => {
105        match $value {
106            Ok(v) => Some(v),
107            Err(_) => None,
108        }
109    };
110    (
111      // Unwraps the contained `Ok` value, otherwise returns `None`.
112      ok_some? $value:expr) => {
113        match $value {
114            Ok(v) => v,
115            Err(_) => return None,
116        }
117    };
118
119    (
120      // Unwraps the contained `Ok` value, or the `Err` value (must be the same type).
121      ok_err $value:expr) => {
122        match $value {
123            Ok(v) => v,
124            Err(v) => v,
125        }
126    };
127
128    (
129      // Unwraps the contained `Err` value, or panics if it's `Ok`.
130      err $value:expr ) => {
131        match $value {
132            Ok(_) => core::panic![],
133            Err(v) => v,
134        }
135    };
136    (
137      // Unwraps the contained `Err` value, or panics the given message if it's `Ok`.
138      err_expect $value:expr, $message:literal) => {
139        match $value {
140            Ok(_) => core::panic!["{}", $message],
141            Err(v) => v,
142        }
143    };
144    (
145      // Unwraps the contained `Err` value, or a provided default if it's `Ok`.
146      err_or $value:expr, $default:expr) => {
147        match $value {
148            Ok(_) => $default,
149            Err(v) => v,
150        }
151    };
152    (
153      // Transforms the `Result` into an `Option`, mapping `Err(E)` to `Some(E)`,
154      // and `Ok(_)` to `None`.
155      err_some $value:expr) => {
156        match $value {
157            Ok(_) => None,
158            Err(e) => Some(e),
159        }
160    };
161    (
162      // Unwraps the contained `Err` value, otherwise returns `None`.
163      err_some? $value:expr) => {
164        match $value {
165            Ok(_) => return None,
166            Err(e) => e,
167        }
168    };
169    (
170
171      // OptRes<T, E>
172      // ------------
173
174      // Unwraps the contained `Some(Ok)` value,
175      // or otherwise either returns the `Some(Err)` value or `None`.
176      sok? $value:expr ) => {
177        match $value {
178            Some(Ok(v)) => v,
179            Some(Err(e)) => return Some(Err(e)),
180            None => return None,
181        }
182    };
183    (
184      // Unwraps the contained `Some(Ok)` value,
185      // or panics if it's `Some(Err)` or `None`.
186      sok $value:expr ) => {
187        match $value {
188            Some(Ok(v)) => v,
189            Some(Err(_)) => core::panic![],
190            None => core::panic![],
191        }
192    };
193
194    (
195      // Unwraps the contained `Some(Ok)` value,
196      // or panics with the given message if it's `Some(Err)` or `None`.
197      sok_expect $value:expr, $message:literal) => {
198        match $value {
199            Some(Ok(v)) => v,
200            Some(Err(_)) => core::panic!["{}", $message],
201            None => core::panic!["{}", $message],
202        }
203    };
204    (
205      // Unwraps the contained `Some(Ok)` value,
206      // or a provided default if it's `Some(Err)` or `None`.
207      sok_or $value:expr, $default:expr) => {
208        match $value {
209            Some(Ok(v)) => v,
210            Some(Err(_)) => $default,
211            None => $default,
212        }
213    };
214    (
215      // Unwraps the contained `Some(Err)` value,
216      // or panics if it's `Some(Ok)` or `None`.
217      serr $value:expr ) => {
218        match $value {
219            Some(Ok(_)) => core::panic![],
220            Some(Err(v)) => v,
221            None => core::panic![],
222        }
223    };
224    (
225      // Unwraps the contained `Some(Err)` value,
226      // or panics with the given message if it's `Some(Ok)` or `None`.
227      serr_expect $value:expr, $message:literal) => {
228        match $value {
229            Some(Ok(_)) => core::panic!["{}", $message],
230            Some(Err(v)) => v,
231            None => core::panic!["{}", $message],
232        }
233    };
234    (
235      // Unwraps the contained `Some(Err)` value,
236      // or a provided default if it's `Some(Ok)` or `None`.
237      serr_or $value:expr, $default:expr) => {
238        match $value {
239            Some(Ok(_)) => $default,
240            Some(Err(v)) => v,
241            None => $default,
242        }
243    };
244}
245#[doc(inline)]
246pub use unwrap;
247
248#[cfg(test)]
249mod tests {
250    #[cfg(feature = "std")]
251    use crate::Panic;
252    use crate::{serr, sok, unwrap, OptRes};
253
254    const OPTION_SOME: Option<bool> = Some(true);
255    const OPTION_NONE: Option<bool> = None;
256
257    const RESULT_OK: Result<bool, bool> = Ok(true);
258    const RESULT_ERR: Result<bool, bool> = Err(true);
259
260    const OPTRES_OK: OptRes<bool, bool> = sok(true);
261    const OPTRES_ERR: OptRes<bool, bool> = serr(true);
262    const OPTRES_NONE: OptRes<bool, bool> = None;
263
264    #[test]
265    fn test_unwrap_option() {
266        assert![unwrap![some OPTION_SOME]];
267        assert![unwrap![some_expect OPTION_SOME, "ERR"]];
268        assert_eq![unwrap![some_or OPTION_SOME, false], true];
269        assert_eq![unwrap![some_or OPTION_NONE, false], false];
270    }
271    #[test] #[cfg(feature = "std")] #[rustfmt::skip]
272    fn test_unwrap_option_panic() {
273        assert![Panic::catch(|| { assert![unwrap![some OPTION_NONE]] }).is_err()];
274        assert![Panic::catch(|| { assert![unwrap![some_expect OPTION_NONE, "ERR"]] }).is_err()];
275    }
276
277    #[test]
278    fn test_unwrap_result() {
279        assert![unwrap![ok RESULT_OK]];
280        assert![unwrap![ok_expect RESULT_OK, "ERR"]];
281        assert_eq![unwrap![ok_or RESULT_OK, false], true];
282        assert_eq![unwrap![ok_or RESULT_ERR, false], false];
283
284        assert![unwrap![err RESULT_ERR]];
285        assert![unwrap![err_expect RESULT_ERR, "ERR"]];
286        assert_eq![unwrap![err_or RESULT_ERR, false], true];
287        assert_eq![unwrap![err_or RESULT_OK, false], false];
288    }
289    #[test] #[cfg(feature = "std")] #[rustfmt::skip]
290    fn test_unwrap_result_panic() {
291        assert![Panic::catch(|| { assert![unwrap![ok RESULT_ERR]] }).is_err()];
292        assert![Panic::catch(|| { assert![unwrap![ok_expect RESULT_ERR, "ERR"]] }).is_err()];
293
294        assert![Panic::catch(|| { assert![unwrap![err RESULT_OK]] }).is_err()];
295        assert![Panic::catch(|| { assert![unwrap![err_expect RESULT_OK, "ERR"]] }).is_err()];
296    }
297
298    #[test]
299    fn test_unwrap_optres() {
300        assert![unwrap![sok OPTRES_OK]];
301        assert![unwrap![sok_expect OPTRES_OK, "ERR"]];
302        assert_eq![unwrap![sok_or OPTRES_OK, false], true];
303        assert_eq![unwrap![sok_or OPTRES_ERR, false], false];
304        assert_eq![unwrap![sok_or OPTRES_NONE, false], false];
305
306        assert![unwrap![serr OPTRES_ERR]];
307        assert![unwrap![serr_expect OPTRES_ERR, "ERR"]];
308        assert_eq![unwrap![serr_or OPTRES_ERR, false], true];
309        assert_eq![unwrap![serr_or OPTRES_OK, false], false];
310        assert_eq![unwrap![serr_or OPTRES_NONE, false], false];
311    }
312    #[test] #[cfg(feature = "std")] #[rustfmt::skip]
313    fn test_unwrap_optres_panic() {
314        assert![Panic::catch(|| { assert![unwrap![sok OPTRES_ERR]] }).is_err()];
315        assert![Panic::catch(|| { assert![unwrap![sok OPTRES_NONE]] }).is_err()];
316        assert![Panic::catch(|| { assert![unwrap![sok_expect OPTRES_ERR, "ERR"]] }).is_err()];
317        assert![Panic::catch(|| { assert![unwrap![sok_expect OPTRES_NONE, "ERR"]] }).is_err()];
318
319        assert![Panic::catch(|| { assert![unwrap![serr OPTRES_OK]] }).is_err()];
320        assert![Panic::catch(|| { assert![unwrap![serr OPTRES_NONE]] }).is_err()];
321        assert![Panic::catch(|| { assert![unwrap![serr_expect OPTRES_OK, "ERR"]] }).is_err()];
322        assert![Panic::catch(|| { assert![unwrap![serr_expect OPTRES_NONE, "ERR"]] }).is_err()];
323    }
324}