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}