konst/
result.rs

1//! `const` equivalents of `Result` methods.
2
3/// For unwrapping `Result`s in const contexts with some error message.
4///
5/// The error type must have a method with this signature:
6///
7/// ```rust
8/// # struct Foo;
9/// # impl Foo {
10/// pub const fn panic(&self) -> ! {
11/// #   loop{}
12/// # }
13/// # }
14/// ```
15///
16/// All the errors from this crate can be used with this macro.
17///
18/// # Example
19///
20/// ### Basic
21///
22#[cfg_attr(feature = "parsing", doc = "```rust")]
23#[cfg_attr(not(feature = "parsing"), doc = "```ignore")]
24/// use konst::{Parser, unwrap_ctx};
25///
26/// let mut parser = Parser::new("hello world");
27///
28/// parser = unwrap_ctx!(parser.strip_prefix("hello "));
29///
30/// assert_eq!(parser.remainder(), "world");
31///
32/// ```
33///
34/// ### Defining error type
35///
36/// ```rust
37/// use konst::unwrap_ctx;
38///
39/// const UNWRAPPED: u32 = {
40///     let res: Result<u32, FooError> = Ok(100);
41///     unwrap_ctx!(res)
42/// };
43///
44/// assert_eq!(UNWRAPPED, 100);
45///
46///
47/// use std::fmt::{self, Display};
48///
49/// #[derive(Debug, Clone, PartialEq)]
50/// pub struct FooError(usize);
51///
52/// impl FooError {
53///     pub const fn panic(&self) -> ! {
54///         panic!("Foo error")
55///         
56///         // Alternatively, using the `const_panic` crate:
57///         //
58///         // const_panic::concat_panic!("Foo errored at offset: ", self.0)
59///     }
60/// }
61///
62/// impl Display for FooError {
63///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64///         fmt::Debug::fmt(self, f)
65///     }
66/// }
67///
68/// impl std::error::Error for FooError {}
69///
70/// ```
71///
72/// If `res` was an error instead, this is the error message you would see:
73///
74/// ```text
75/// error[E0080]: evaluation of constant value failed
76///   --> src/result.rs:55:9
77///    |
78/// 9  |     unwrap_ctx!(res)
79///    |     ---------------- inside `UNWRAPPED` at result_macros_.rs:6:35
80/// ...
81/// 23 |         panic!("Foo error")
82///    |         ^^^^^^^^^^^^^^^^^^^
83///    |         |
84///    |         the evaluated program panicked at 'Foo error', src/result.rs:23:9
85///    |         inside `FooError::panic`
86///
87/// ```
88///
89/// [`Parser`]: ../parsing/struct.Parser.html
90#[doc(inline)]
91pub use konst_kernel::unwrap_ctx;
92
93/// A const equivalent of [`Result::unwrap_or`]
94///
95/// # Example
96///
97/// ```rust
98/// use konst::result;
99///
100/// // Necessary for type inference reasons.
101/// type Res = Result<u32, u32>;
102///
103/// const ARR: &[u32] = &[
104///     result::unwrap_or!(Res::Ok(3), 5),
105///     result::unwrap_or!(Res::Err(8), 13),
106/// ];
107///
108/// assert_eq!(ARR, &[3, 13]);
109///
110/// ```
111///
112#[doc(inline)]
113pub use konst_kernel::res_unwrap_or as unwrap_or;
114
115/// A const equivalent of [`Result::unwrap_or_else`]
116///
117/// # Example
118///
119/// ```rust
120/// use konst::result;
121///
122/// // Necessary for type inference reasons.
123/// type Res = Result<u32, u32>;
124///
125/// const ARR: &[u32] = &[
126///     // You can use a closure-like syntax to run code when the Result argument is Err.
127///     // `return` inside the "closure" returns from the function where this macro is called.
128///     result::unwrap_or_else!(Res::Ok(3), |_| loop{}),
129///     result::unwrap_or_else!(Res::Err(8), |x| x + 5),
130///
131///     // You can also pass functions
132///     result::unwrap_or_else!(Res::Ok(21), add_34),
133///     result::unwrap_or_else!(Res::Err(55), add_34),
134/// ];
135///
136/// assert_eq!(ARR, &[3, 13, 21, 89]);
137///
138/// const fn add_34(n: u32) -> u32 {
139///     n + 34
140/// }
141/// ```
142///
143#[doc(inline)]
144pub use konst_kernel::res_unwrap_or_else as unwrap_or_else;
145
146/// Returns the error in the `Err` variant,
147/// otherwise runs a closure/function with the value in the `Ok` variant.
148///
149/// # Example
150///
151/// ```rust
152/// use konst::result;
153///
154/// // Necessary for type inference reasons.
155/// type Res = Result<u32, u32>;
156///
157/// const ARR: &[u32] = &[
158///     // You can use a closure-like syntax to run code when the Result argument is Ok.
159///     // `return` inside the "closure" returns from the function where this macro is called.
160///     result::unwrap_err_or_else!(Res::Ok(3), |x| x + 2),
161///     result::unwrap_err_or_else!(Res::Err(8), |_| loop{}),
162///
163///     // You can also pass functions
164///     result::unwrap_err_or_else!(Res::Ok(16), add_34),
165///     result::unwrap_err_or_else!(Res::Err(55), add_34),
166/// ];
167///
168/// assert_eq!(ARR, &[5, 8, 50, 55]);
169///
170/// const fn add_34(n: u32) -> u32 {
171///     n + 34
172/// }
173/// ```
174///
175#[doc(inline)]
176pub use konst_kernel::res_unwrap_err_or_else as unwrap_err_or_else;
177
178/// A const equivalent of [`Result::ok`]
179///
180/// # Example
181///
182/// ```rust
183/// use konst::result;
184///
185/// // Necessary for type inference reasons.
186/// type Res = Result<u32, u32>;
187///
188/// const ARR: &[Option<u32>] = &[
189///     result::ok!(Res::Ok(3)),
190///     result::ok!(Res::Err(8)),
191/// ];
192///
193/// assert_eq!(ARR, &[Some(3), None]);
194///
195/// ```
196///
197#[doc(inline)]
198pub use konst_kernel::res_ok as ok;
199
200/// A const equivalent of [`Result::err`]
201///
202/// # Example
203///
204/// ```rust
205/// use konst::result;
206///
207/// // Necessary for type inference reasons.
208/// type Res = Result<u32, u32>;
209///
210/// const ARR: &[Option<u32>] = &[
211///     result::err!(Res::Ok(3)),
212///     result::err!(Res::Err(8)),
213/// ];
214///
215/// assert_eq!(ARR, &[None, Some(8)]);
216///
217/// ```
218///
219#[doc(inline)]
220pub use konst_kernel::res_err as err;
221
222/// A const equivalent of [`Result::map`]
223///
224/// # Example
225///
226/// ```rust
227/// use konst::result;
228///
229/// // Necessary for type inference reasons.
230/// type Res = Result<u32, u32>;
231///
232/// const ARR: &[Res] = &[
233///     // You can use a closure-like syntax to run code when the Result argument is Ok.
234///     // `return` inside the "closure" returns from the function where this macro is called.
235///     result::map!(Res::Ok(3), |x| x + 2),
236///     result::map!(Res::Err(8), |_| loop{}),
237///
238///     // You can also pass functions
239///     result::map!(Res::Ok(16), add_34),
240///     result::map!(Res::Err(55), add_34),
241/// ];
242///
243/// assert_eq!(ARR, &[Ok(5), Err(8), Ok(50), Err(55)]);
244///
245/// const fn add_34(n: u32) -> u32 {
246///     n + 34
247/// }
248/// ```
249///
250#[doc(inline)]
251pub use konst_kernel::res_map as map;
252
253/// A const equivalent of [`Result::map_err`]
254///
255/// # Example
256///
257/// ```rust
258/// use konst::result;
259///
260/// // Necessary for type inference reasons.
261/// type Res = Result<u32, u32>;
262///
263/// const ARR: &[Res] = &[
264///     // You can use a closure-like syntax to run code when the Result argument is Ok.
265///     // `return` inside the "closure" returns from the function where this macro is called.
266///     result::map_err!(Res::Ok(3), |_| loop{}),
267///     result::map_err!(Res::Err(8), |x| x + 5),
268///
269///     // You can also pass functions
270///     result::map_err!(Res::Ok(16), add_34),
271///     result::map_err!(Res::Err(55), add_34),
272/// ];
273///
274/// assert_eq!(ARR, &[Ok(3), Err(13), Ok(16), Err(89)]);
275///
276/// const fn add_34(n: u32) -> u32 {
277///     n + 34
278/// }
279/// ```
280///
281#[doc(inline)]
282pub use konst_kernel::res_map_err as map_err;
283
284/// A const equivalent of [`Result::and_then`]
285///
286/// # Example
287///
288/// ```rust
289/// use konst::result;
290///
291/// // Necessary for type inference reasons.
292/// type Res = Result<u32, u32>;
293///
294/// const ARR: &[Res] = &[
295///     // You can use a closure-like syntax to run code when the Result argument is Ok.
296///     // `return` inside the "closure" returns from the function where this macro is called.
297///     result::and_then!(Res::Ok(1), |x| Ok(x + 2)),
298///     result::and_then!(Res::Ok(10), |x| Err(x + 4)),
299///     result::and_then!(Res::Err(20), |_| loop{}),
300///
301///     // You can also pass functions
302///     result::and_then!(Res::Ok(40), add_2),
303///     result::and_then!(Res::Ok(40), add_5),
304///     result::and_then!(Res::Err(60), add_5),
305/// ];
306///
307/// assert_eq!(ARR, &[Ok(3), Err(14), Err(20), Ok(42), Err(45), Err(60)]);
308///
309/// const fn add_2(n: u32) -> Res {
310///     Ok(n + 2)
311/// }
312/// const fn add_5(n: u32) -> Res {
313///     Err(n + 5)
314/// }
315/// ```
316///
317#[doc(inline)]
318pub use konst_kernel::res_and_then as and_then;
319
320/// A const equivalent of [`Result::or_else`]
321///
322/// # Example
323///
324/// ```rust
325/// use konst::result;
326///
327/// // Necessary for type inference reasons.
328/// type Res = Result<u32, u32>;
329///
330/// const ARR: &[Res] = &[
331///     // You can use a closure-like syntax to run code when the Result argument is Err.
332///     // `return` inside the "closure" returns from the function where this macro is called.
333///     result::or_else!(Res::Ok(1), |_| loop{}),
334///     result::or_else!(Res::Err(20), |x| Ok(x + 5)),
335///     result::or_else!(Res::Err(20), |x| Err(x + 7)),
336///
337///     // You can also pass functions
338///     result::or_else!(Res::Ok(40), add_2),
339///     result::or_else!(Res::Err(60), add_2),
340///     result::or_else!(Res::Err(60), add_5),
341/// ];
342///
343/// assert_eq!(ARR, &[Ok(1), Ok(25), Err(27), Ok(40), Ok(62), Err(65)]);
344///
345/// const fn add_2(n: u32) -> Res {
346///     Ok(n + 2)
347/// }
348/// const fn add_5(n: u32) -> Res {
349///     Err(n + 5)
350/// }
351/// ```
352///
353#[doc(inline)]
354pub use konst_kernel::res_or_else as or_else;