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