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}