konst/
option.rs

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