konst/option.rs
1//! `const` equivalents of `Option` methods.
2
3/// A const equivalent of [`Option::unwrap`]
4///
5/// # Const stabilization
6///
7/// The equivalent std function was const-stabilized in Rust 1.83.0.
8///
9/// # Example
10///
11/// ```rust
12/// use konst::option::unwrap;
13///
14/// use std::num::NonZeroUsize;
15///
16/// const TEN: NonZeroUsize = unwrap!(NonZeroUsize::new(10));
17///
18/// assert_eq!(TEN.get(), 10);
19/// ```
20#[doc(inline)]
21pub use konst_kernel::opt_unwrap as unwrap;
22
23/// A const equivalent of [`Option::unwrap_or`]
24///
25/// # Example
26///
27/// ```
28/// use konst::option;
29///
30/// const ARR: &[u32] = &[
31/// option::unwrap_or!(Some(3), 10000),
32/// option::unwrap_or!(None, 5),
33/// ];
34///
35/// assert_eq!(ARR, &[3, 5]);
36///
37/// ```
38///
39#[doc(inline)]
40pub use konst_kernel::opt_unwrap_or as unwrap_or;
41
42/// A const equivalent of [`Option::unwrap_or_else`]
43///
44/// # Example
45///
46/// ```
47/// use konst::option;
48///
49/// const ARR: &[u32] = &[
50/// // You can use a closure-like syntax to run code when the Option argument is None.
51/// // `return` inside the "closure" returns from the function where this macro is called.
52/// option::unwrap_or_else!(Some(3), || loop{}),
53/// option::unwrap_or_else!(None, || 5),
54///
55/// // You can also pass functions
56/// option::unwrap_or_else!(Some(8), thirteen),
57/// option::unwrap_or_else!(None, thirteen),
58/// ];
59///
60/// assert_eq!(ARR, &[3, 5, 8, 13]);
61///
62/// const fn thirteen() -> u32 {
63/// 13
64/// }
65/// ```
66///
67#[doc(inline)]
68pub use konst_kernel::opt_unwrap_or_else as unwrap_or_else;
69
70/// A const equivalent of [`Option::ok_or`]
71///
72/// # Example
73///
74/// ```
75/// use konst::option;
76///
77/// const ARR: &[Result<u32, u32>] = &[
78/// option::ok_or!(Some(3), 10000),
79/// option::ok_or!(None, 5),
80/// ];
81///
82/// assert_eq!(ARR, &[Ok(3), Err(5)]);
83///
84/// ```
85#[doc(inline)]
86pub use konst_kernel::opt_ok_or as ok_or;
87
88/// A const equivalent of [`Option::ok_or_else`]
89///
90/// # Example
91///
92/// ```
93/// use konst::option;
94///
95/// const ARR: &[Result<u32, u32>] = &[
96/// // You can use a closure-like syntax to run code when the Option argument is None.
97/// // `return` inside the "closure" returns from the function where this macro is called.
98/// option::ok_or_else!(Some(3), || loop{}),
99/// option::ok_or_else!(None, || 5),
100///
101/// // You can also pass functions
102/// option::ok_or_else!(Some(8), thirteen),
103/// option::ok_or_else!(None, thirteen),
104/// ];
105///
106/// assert_eq!(ARR, &[Ok(3), Err(5), Ok(8), Err(13)]);
107///
108/// const fn thirteen() -> u32 {
109/// 13
110/// }
111/// ```
112#[doc(inline)]
113pub use konst_kernel::opt_ok_or_else as ok_or_else;
114
115/// A const equivalent of [`Option::map`]
116///
117/// # Example
118///
119/// ```
120/// use konst::option;
121///
122/// const ARR: &[Option<u32>] = &[
123/// // You can use a closure-like syntax to pass code that maps the Some variant.
124/// // `return` inside the "closure" returns from the function where this macro is called.
125/// option::map!(Some(3), |x| x * 3),
126/// option::map!(None::<u32>, |_| loop{}),
127///
128/// // You can also pass functions
129/// option::map!(Some(8), double),
130/// option::map!(None::<u32>, double),
131/// ];
132///
133/// assert_eq!(ARR, &[Some(9), None, Some(16), None]);
134///
135/// const fn double(x: u32) -> u32 {
136/// x * 2
137/// }
138///
139/// ```
140#[doc(inline)]
141pub use konst_kernel::opt_map as map;
142
143/// A const equivalent of [`Option::and_then`]
144///
145/// # Example
146///
147/// ```
148/// use konst::option;
149///
150/// const ARR: &[Option<u32>] = &[
151/// // You can use a closure-like syntax to pass code that uses the value in the Some variant.
152/// // `return` inside the "closure" returns from the function where this macro is called.
153/// option::and_then!(Some(3), |x| Some(x * 3)),
154/// option::and_then!(Some(3), |_| None),
155/// option::and_then!(None::<u32>, |_| loop{}),
156///
157/// // You can also pass functions
158/// option::and_then!(Some(23), checked_sub),
159/// option::and_then!(Some(9), checked_sub),
160/// option::and_then!(None::<u32>, checked_sub),
161/// ];
162///
163/// assert_eq!(ARR, &[Some(9), None, None, Some(13), None, None]);
164///
165/// const fn checked_sub(x: u32) -> Option<u32> {
166/// # /*
167/// x.checked_sub(10)
168/// # */
169/// # let (ret, overflowed) = x.overflowing_sub(10);
170/// # if overflowed { None } else { Some(ret) }
171/// }
172///
173/// ```
174#[doc(inline)]
175pub use konst_kernel::opt_and_then as and_then;
176
177/// A const equivalent of [`Option::or_else`]
178///
179/// # Example
180///
181/// ```
182/// use konst::option;
183///
184/// const ARR: &[Option<u32>] = &[
185/// // You can use a closure-like syntax to pass code that runs on None.
186/// // `return` inside the "closure" returns from the function where this macro is called.
187/// option::or_else!(Some(3), || loop{}),
188/// option::or_else!(None::<u32>, || Some(5)),
189///
190/// // You can also pass functions
191/// option::or_else!(Some(8), thirteen),
192/// option::or_else!(None::<u32>, thirteen),
193/// ];
194///
195/// assert_eq!(ARR, &[Some(3), Some(5), Some(8), Some(13)]);
196///
197/// const fn thirteen() -> Option<u32> {
198/// Some(13)
199/// }
200///
201/// ```
202#[doc(inline)]
203pub use konst_kernel::opt_or_else as or_else;
204
205/// A const equivalent of [`Option::flatten`]
206///
207/// # Const stabilization
208///
209/// The equivalent std function was const-stabilized in Rust 1.83.0.
210///
211/// # Example
212///
213/// ```
214/// use konst::option;
215///
216/// const ARR: &[Option<u32>] = &[
217/// option::flatten!(Some(Some(8))),
218/// option::flatten!(None),
219/// ];
220///
221/// assert_eq!(ARR, &[Some(8), None]);
222///
223/// ```
224#[doc(inline)]
225pub use konst_kernel::opt_flatten as flatten;
226
227/// A const equivalent of [`Option::filter`]
228///
229/// # Example
230///
231/// ```
232/// use konst::option;
233///
234/// const ARR: &[Option<u32>] = &[
235/// // You can use a closure-like syntax to pass code that filters the Some variant.
236/// // `return` inside the "closure" returns from the function where this macro is called.
237/// option::filter!(Some(0), |&x| x == 0),
238/// option::filter!(Some(1), |x| *x == 0),
239/// option::filter!(None, |_| loop{}),
240///
241/// // You can also pass functions
242/// option::filter!(Some(3), is_odd),
243/// option::filter!(Some(4), is_odd),
244/// option::filter!(None, is_odd),
245/// ];
246///
247/// assert_eq!(ARR, &[Some(0), None, None, Some(3), None, None]);
248///
249/// const fn is_odd(x: &u32) -> bool {
250/// *x % 2 == 1
251/// }
252///
253/// ```
254#[doc(inline)]
255pub use konst_kernel::opt_filter as filter;
256
257/// A const equivalent of the [`Option::copied`] method.
258///
259/// # Const stabilization
260///
261/// The equivalent std function was const-stabilized in Rust 1.83.0.
262///
263/// # Example
264///
265/// ```rust
266/// use konst::option;
267///
268/// const fn get_last(slice: &[u64]) -> Option<u64> {
269/// option::copied(slice.last())
270/// }
271///
272/// assert_eq!(get_last(&[]), None);
273/// assert_eq!(get_last(&[16]), Some(16));
274/// assert_eq!(get_last(&[3, 5, 8, 13]), Some(13));
275///
276///
277/// ```
278pub const fn copied<T: Copy>(opt: Option<&T>) -> Option<T> {
279 match opt {
280 Some(x) => Some(*x),
281 None => None,
282 }
283}
284
285declare_generic_const! {
286 /// Usable to do `[None::<T>; LEN]` when `T` is non-`Copy`.
287 ///
288 /// As of Rust 1.65.0, `[None::<T>; LEN]` is not valid for non-`Copy` types,
289 /// but `[CONST; LEN]` does work, like in the example below.
290 ///
291 /// # Example
292 ///
293 /// ```rust
294 /// use konst::option::NONE;
295 ///
296 /// use std::mem::{self, MaybeUninit};
297 ///
298 /// const TEN: [Option<String>; 10] = [NONE::V; 10];
299 ///
300 /// let ten = [NONE::<String>::V; 10];
301 ///
302 /// // the `vec` macro only needs `Option<String>` to be clonable, not Copy.
303 /// assert_eq!(vec![None::<String>; 10], TEN);
304 ///
305 /// assert_eq!(vec![None::<String>; 10], ten);
306 ///
307 for[T]
308 pub const NONE[T]: Option<T> = None;
309}