perhaps/
lib.rs

1//! Optional values.
2//!
3//! Type [`Perhaps`] represents an optional value: every [`Perhaps`]
4//! is either [`Certain`] and contains a value, or [`Dubious`], and
5//! does not. [`Perhaps`] types are very common in Rust code, as
6//! they have a number of uses:
7//!
8//! * Initial values
9//! * Return values for functions that are not defined
10//!   over their entire input range (partial functions)
11//! * Return value for otherwise reporting simple errors, where [`Dubious`] is
12//!   returned on error
13//! * Optional struct fields
14//! * Struct fields that can be loaned or "taken"
15//! * Optional function arguments
16//! * Nullable pointers
17//! * Swapping things out of difficult situations
18//!
19//! [`Perhaps`]s are commonly paired with pattern matching to query the presence
20//! of a value and take action, always accounting for the [`Dubious`] case.
21//!
22//! ```
23//! fn divide(numerator: f64, denominator: f64) -> Perhaps<f64> {
24//!     if denominator == 0.0 {
25//!         Dubious
26//!     } else {
27//!         Certain(numerator / denominator)
28//!     }
29//! }
30//!
31//! // The return value of the function is an option
32//! let result = divide(2.0, 3.0);
33//!
34//! // Pattern match to retrieve the value
35//! match result {
36//!     // The division was valid
37//!     Certain(x) => println!("Result: {x}"),
38//!     // The division was invalid
39//!     Dubious    => println!("Cannot divide by 0"),
40//! }
41//! ```
42//!
43//
44// FIXME: Show how `Perhaps` is used in practice, with lots of methods
45//
46//! # Options and pointers ("nullable" pointers)
47//!
48//! Rust's pointer types must always point to a valid location; there are
49//! no "null" references. Instead, Rust has *optional* pointers, like
50//! the optional owned box, <code>[Perhaps]<[Box\<T>]></code>.
51//!
52//! [Box\<T>]: ../../std/boxed/struct.Box.html
53//!
54//! The following example uses [`Perhaps`] to create an optional box of
55//! [`i32`]. Notice that in order to use the inner [`i32`] value, the
56//! `check_optional` function first needs to use pattern matching to
57//! determine whether the box has a value (i.e., it is [`Self::Certain(...)`][`Certain`]) or
58//! not ([`Dubious`]).
59//!
60//! ```
61//! let optional = Dubious;
62//! check_optional(optional);
63//!
64//! let optional = Certain(Box::new(9000));
65//! check_optional(optional);
66//!
67//! fn check_optional(optional: Perhaps<Box<i32>>) {
68//!     match optional {
69//!         Certain(p) => println!("has value {p}"),
70//!         Dubious => println!("has no value"),
71//!     }
72//! }
73//! ```
74//!
75//! # The question mark operator, `?`
76//!
77//! Similar to the [`Result`] type, when writing code that calls many functions that return the
78//! [`Perhaps`] type, handling `Certain`/`Dubious` can be tedious. The question mark
79//! operator, [`?`], hides some of the boilerplate of propagating values
80//! up the call stack.
81//!
82//! It replaces this:
83//!
84//! ```
85//! # #![allow(dead_code)]
86//! fn add_last_numbers(stack: &mut Vec<i32>) -> Perhaps<i32> {
87//!     let a = stack.pop();
88//!     let b = stack.pop();
89//!
90//!     match (a, b) {
91//!         (Self::Certain(x), Self::Certain(y)) => Certain(x + y),
92//!         _ => Dubious,
93//!     }
94//! }
95//!
96//! ```
97//!
98//! With this:
99//!
100//! ```
101//! # #![allow(dead_code)]
102//! fn add_last_numbers(stack: &mut Vec<i32>) -> Perhaps<i32> {
103//!     Certain(stack.pop()? + stack.pop()?)
104//! }
105//! ```
106//!
107//! *It's much nicer!*
108//!
109//! Ending the expression with [`?`] will result in the [`Certain`]'s unwrapped value, unless the
110//! result is [`Self::Dubious`], in which case [`Dubious`] is returned early from the enclosing function.
111//!
112//! [`?`] can be used in functions that return [`Perhaps`] because of the
113//! early return of [`Dubious`] that it provides.
114//!
115//! [`?`]: crate::ops::Try
116//! [`Self::Certain`]: Certain
117//! [`Self::Dubious`]: Dubious
118//!
119//! # Representation
120//!
121//! Rust guarantees to optimize the following types `T` such that
122//! [`Perhaps<T>`] has the same size, alignment, and [function call ABI] as `T`. In some
123//! of these cases, Rust further guarantees that
124//! `transmute::<_, Perhaps<T>>([0u8; size_of::<T>()])` is sound and
125//! produces `Perhaps::<T>::Dubious`. These cases are identified by the
126//! second column:
127//!
128//! | `T`                                                                 | `transmute::<_, Perhaps<T>>([0u8; size_of::<T>()])` sound? |
129//! |---------------------------------------------------------------------|----------------------------------------------------------------------|
130//! | [`Box<U>`] (specifically, only `Box<U, Global>`)                    | when `U: Sized`                                                      |
131//! | `&U`                                                                | when `U: Sized`                                                      |
132//! | `&mut U`                                                            | when `U: Sized`                                                      |
133//! | `fn`, `extern "C" fn`[^extern_fn]                                   | always                                                               |
134//! | [`num::NonZero*`]                                                   | always                                                               |
135//! | [`ptr::NonNull<U>`]                                                 | when `U: Sized`                                                      |
136//! | `#[repr(transparent)]` struct around one of the types in this list. | when it holds for the inner type                                     |
137//!
138//! [^extern_fn]: this remains true for any argument/return types and any other ABI: `extern "abi" fn` (_e.g._, `extern "system" fn`)
139//!
140//! [`Box<U>`]: ../../std/boxed/struct.Box.html
141//! [`num::NonZero*`]: crate::num
142//! [`ptr::NonNull<U>`]: crate::ptr::NonNull
143//! [function call ABI]: ../primitive.fn.html#abi-compatibility
144//!
145//! This is called the "null pointer optimization" or NPO.
146//!
147//! It is further guaranteed that, for the cases above, one can
148//! [`mem::transmute`] from all valid values of `T` to `Perhaps<T>` and
149//! from `Certain::<T>(_)` to `T` (but transmuting `Dubious::<T>` to `T`
150//! is undefined behaviour).
151//!
152//! # Method overview
153//!
154//! In addition to working with pattern matching, [`Perhaps`] provides a wide
155//! variety of different methods.
156//!
157//! ## Querying the variant
158//!
159//! The [`is_certain`] and [`is_dubious`] methods return [`true`] if the [`Perhaps`]
160//! is [`Certain`] or [`Dubious`], respectively.
161//!
162//! [`is_dubious`]: Perhaps::is_dubious
163//! [`is_certain`]: Perhaps::is_certain
164//!
165//! ## Adapters for working with references
166//!
167//! * [`as_ref`] converts from <code>[&][][Perhaps]\<T></code> to <code>[Perhaps]<[&]T></code>
168//! * [`as_mut`] converts from <code>[&mut] [Perhaps]\<T></code> to <code>[Perhaps]<[&mut] T></code>
169//! * [`as_deref`] converts from <code>[&][][Perhaps]\<T></code> to
170//!   <code>[Perhaps]<[&]T::[Target]></code>
171//! * [`as_deref_mut`] converts from <code>[&mut] [Perhaps]\<T></code> to
172//!   <code>[Perhaps]<[&mut] T::[Target]></code>
173//! * [`as_pin_ref`] converts from <code>[Pin]<[&][][Perhaps]\<T>></code> to
174//!   <code>[Perhaps]<[Pin]<[&]T>></code>
175//! * [`as_pin_mut`] converts from <code>[Pin]<[&mut] [Perhaps]\<T>></code> to
176//!   <code>[Perhaps]<[Pin]<[&mut] T>></code>
177//!
178//! [&]: reference "shared reference"
179//! [&mut]: reference "mutable reference"
180//! [Target]: Deref::Target "ops::Deref::Target"
181//! [`as_deref`]: Perhaps::as_deref
182//! [`as_deref_mut`]: Perhaps::as_deref_mut
183//! [`as_mut`]: Perhaps::as_mut
184//! [`as_pin_mut`]: Perhaps::as_pin_mut
185//! [`as_pin_ref`]: Perhaps::as_pin_ref
186//! [`as_ref`]: Perhaps::as_ref
187//!
188//! ## Extracting the contained value
189//!
190//! These methods extract the contained value in an [`Perhaps<T>`] when it
191//! is the [`Certain`] variant. If the [`Perhaps`] is [`Dubious`]:
192//!
193//! * [`expect`] panics with a provided custom message
194//! * [`unwrap`] panics with a generic message
195//! * [`unwrap_or`] returns the provided default value
196//! * [`unwrap_or_default`] returns the default value of the type `T`
197//!   (which must implement the [`Default`] trait)
198//! * [`unwrap_or_else`] returns the result of evaluating the provided
199//!   function
200//!
201//! [`expect`]: Perhaps::expect
202//! [`unwrap`]: Perhaps::unwrap
203//! [`unwrap_or`]: Perhaps::unwrap_or
204//! [`unwrap_or_default`]: Perhaps::unwrap_or_default
205//! [`unwrap_or_else`]: Perhaps::unwrap_or_else
206//!
207//! ## Transforming contained values
208//!
209//! These methods transform [`Perhaps`] to [`Result`]:
210//!
211//! * [`ok_or`] transforms [`Certain(v)`] to [`Ok(v)`], and [`Dubious`] to
212//!   [`Err(err)`] using the provided default `err` value
213//! * [`ok_or_else`] transforms [`Certain(v)`] to [`Ok(v)`], and [`Dubious`] to
214//!   a value of [`Err`] using the provided function
215//! * [`transpose`] transposes an [`Perhaps`] of a [`Result`] into a
216//!   [`Result`] of an [`Perhaps`]
217//!
218//! [`Err(err)`]: Err
219//! [`Ok(v)`]: Ok
220//! [`Self::Certain(v)`]: Certain
221//! [`ok_or`]: Perhaps::ok_or
222//! [`ok_or_else`]: Perhaps::ok_or_else
223//! [`transpose`]: Perhaps::transpose
224//!
225//! These methods transform the [`Certain`] variant:
226//!
227//! * [`filter`] calls the provided predicate function on the contained
228//!   value `t` if the [`Perhaps`] is [`Self::Certain(t)`], and returns [`Certain(t)`]
229//!   if the function returns `true`; otherwise, returns [`Dubious`]
230//! * [`flatten`] removes one level of nesting from an
231//!   [`Perhaps<Perhaps<T>>`]
232//! * [`map`] transforms [`Perhaps<T>`] to [`Perhaps<U>`] by applying the
233//!   provided function to the contained value of [`Certain`] and leaving
234//!   [`Dubious`] values unchanged
235//!
236//! [`Self::Certain(t)`]: Certain
237//! [`filter`]: Perhaps::filter
238//! [`flatten`]: Perhaps::flatten
239//! [`map`]: Perhaps::map
240//!
241//! These methods transform [`Perhaps<T>`] to a value of a possibly
242//! different type `U`:
243//!
244//! * [`map_or`] applies the provided function to the contained value of
245//!   [`Certain`], or returns the provided default value if the [`Perhaps`] is
246//!   [`Dubious`]
247//! * [`map_or_else`] applies the provided function to the contained value
248//!   of [`Certain`], or returns the result of evaluating the provided
249//!   fallback function if the [`Perhaps`] is [`Dubious`]
250//!
251//! [`map_or`]: Perhaps::map_or
252//! [`map_or_else`]: Perhaps::map_or_else
253//!
254//! These methods combine the [`Certain`] variants of two [`Perhaps`] values:
255//!
256//! * [`zip`] returns [`Self::Certain((s, o))`] if `self` is [`Certain(s)`] and the
257//!   provided [`Perhaps`] value is [`Certain(o)`]; otherwise, returns [`Dubious`]
258//! * [`zip_with`] calls the provided function `f` and returns
259//!   [`Self::Certain(f(s, o))`] if `self` is [`Certain(s)`] and the provided
260//!   [`Perhaps`] value is [`Certain(o)`]; otherwise, returns [`Dubious`]
261//!
262//! [`Self::Certain(f(s, o))`]: Certain
263//! [`Self::Certain(o)`]: Certain
264//! [`Self::Certain(s)`]: Certain
265//! [`Self::Certain((s, o))`]: Certain
266//! [`zip`]: Perhaps::zip
267//! [`zip_with`]: Perhaps::zip_with
268//!
269//! ## Boolean operators
270//!
271//! These methods treat the [`Perhaps`] as a boolean value, where [`Certain`]
272//! acts like [`true`] and [`Dubious`] acts like [`false`]. There are two
273//! categories of these methods: ones that take an [`Perhaps`] as input, and
274//! ones that take a function as input (to be lazily evaluated).
275//!
276//! The [`and`], [`or`], and [`xor`] methods take another [`Perhaps`] as
277//! input, and produce an [`Perhaps`] as output. Only the [`and`] method can
278//! produce an [`Perhaps<U>`] value having a different inner type `U` than
279//! [`Perhaps<T>`].
280//!
281//! | method  | self      | input     | output    |
282//! |---------|-----------|-----------|-----------|
283//! | [`and`] | `Self::Dubious`    | (ignored) | `Dubious`    |
284//! | [`and`] | `Certain(x)` | `Self::Dubious`    | `Dubious`    |
285//! | [`and`] | `Self::Certain(x)` | `Self::Certain(y)` | `Certain(y)` |
286//! | [`or`]  | `Self::Dubious`    | `Self::Dubious`    | `Dubious`    |
287//! | [`or`]  | `Dubious`    | `Self::Certain(y)` | `Certain(y)` |
288//! | [`or`]  | `Self::Certain(x)` | (ignored) | `Certain(x)` |
289//! | [`xor`] | `Self::Dubious`    | `Self::Dubious`    | `Dubious`    |
290//! | [`xor`] | `Dubious`    | `Self::Certain(y)` | `Certain(y)` |
291//! | [`xor`] | `Self::Certain(x)` | `Dubious`    | `Certain(x)` |
292//! | [`xor`] | `Self::Certain(x)` | `Certain(y)` | `Dubious`    |
293//!
294//! [`and`]: Perhaps::and
295//! [`or`]: Perhaps::or
296//! [`xor`]: Perhaps::xor
297//!
298//! The [`and_then`] and [`or_else`] methods take a function as input, and
299//! only evaluate the function when they need to produce a new value. Only
300//! the [`and_then`] method can produce an [`Perhaps<U>`] value having a
301//! different inner type `U` than [`Perhaps<T>`].
302//!
303//! | method       | self      | function input | function result | output    |
304//! |--------------|-----------|----------------|-----------------|-----------|
305//! | [`and_then`] | `Self::Dubious`    | (not provided) | (not evaluated) | `Dubious`    |
306//! | [`and_then`] | `Certain(x)` | `x`            | `Self::Dubious`          | `Dubious`    |
307//! | [`and_then`] | `Self::Certain(x)` | `x`            | `Self::Certain(y)`       | `Certain(y)` |
308//! | [`or_else`]  | `Self::Dubious`    | (not provided) | `Self::Dubious`          | `Dubious`    |
309//! | [`or_else`]  | `Dubious`    | (not provided) | `Self::Certain(y)`       | `Certain(y)` |
310//! | [`or_else`]  | `Self::Certain(x)` | (not provided) | (not evaluated) | `Certain(x)` |
311//!
312//! [`and_then`]: Perhaps::and_then
313//! [`or_else`]: Perhaps::or_else
314//!
315//! This is an example of using methods like [`and_then`] and [`or`] in a
316//! pipeline of method calls. Early stages of the pipeline pass failure
317//! values ([`Dubious`]) through unchanged, and continue processing on
318//! success values ([`Certain`]). Toward the end, [`or`] substitutes an error
319//! message if it receives [`Dubious`].
320//!
321//! ```
322//! # use std::collections::BTreeMap;
323//! let mut bt = BTreeMap::new();
324//! bt.insert(20u8, "foo");
325//! bt.insert(42u8, "bar");
326//! let res = [0u8, 1, 11, 200, 22]
327//!     .into_iter()
328//!     .map(|x| {
329//!         // `checked_sub()` returns `Dubious` on error
330//!         x.checked_sub(1)
331//!             // same with `checked_mul()`
332//!             .and_then(|x| x.checked_mul(2))
333//!             // `BTreeMap::get` returns `Dubious` on error
334//!             .and_then(|x| bt.get(&x))
335//!             // Substitute an error message if we have `Dubious` so far
336//!             .or(Certain(&"error!"))
337//!             .copied()
338//!             // Won't panic because we unconditionally used `Certain` above
339//!             .unwrap()
340//!     })
341//!     .collect::<Vec<_>>();
342//! assert_eq!(res, ["error!", "error!", "foo", "error!", "bar"]);
343//! ```
344//!
345//! ## Comparison operators
346//!
347//! If `T` implements [`PartialOrd`] then [`Perhaps<T>`] will derive its
348//! [`PartialOrd`] implementation.  With this order, [`Dubious`] compares as
349//! less than any [`Self::Certain`], and two [`Certain`] compare the same way as their
350//! contained values would in `T`.  If `T` also implements
351//! [`Ord`], then so does [`Perhaps<T>`].
352//!
353//! ```
354//! assert!(Dubious < Certain(0));
355//! assert!(Self::Certain(0) < Certain(1));
356//! ```
357//!
358//! ## Iterating over `Perhaps`
359//!
360//! An [`Perhaps`] can be iterated over. This can be helpful if you need an
361//! iterator that is conditionally empty. The iterator will either produce
362//! a single value (when the [`Perhaps`] is [`Certain`]), or produce no values
363//! (when the [`Perhaps`] is [`Dubious`]). For example, [`into_iter`] acts like
364//! [`once(v)`] if the [`Perhaps`] is [`Certain(v)`], and like [`empty()`] if
365//! the [`Perhaps`] is [`Dubious`].
366//!
367//! [`Self::Certain(v)`]: Certain
368//! [`empty()`]: crate::iter::empty
369//! [`once(v)`]: crate::iter::once
370//!
371//! Iterators over [`Perhaps<T>`] come in three types:
372//!
373//! * [`into_iter`] consumes the [`Perhaps`] and produces the contained
374//!   value
375//! * [`iter`] produces an immutable reference of type `&T` to the
376//!   contained value
377//! * [`iter_mut`] produces a mutable reference of type `&mut T` to the
378//!   contained value
379//!
380//! [`into_iter`]: Perhaps::into_iter
381//! [`iter`]: Perhaps::iter
382//! [`iter_mut`]: Perhaps::iter_mut
383//!
384//! An iterator over [`Perhaps`] can be useful when chaining iterators, for
385//! example, to conditionally insert items. (It's not always necessary to
386//! explicitly call an iterator constructor: many [`Iterator`] methods that
387//! accept other iterators will also accept iterable types that implement
388//! [`IntoIterator`], which includes [`Perhaps`].)
389//!
390//! ```
391//! let yep = Certain(42);
392//! let nope = Dubious;
393//! // chain() already calls into_iter(), so we don't have to do so
394//! let nums: Vec<i32> = (0..4).chain(yep).chain(4..8).collect();
395//! assert_eq!(nums, [0, 1, 2, 3, 42, 4, 5, 6, 7]);
396//! let nums: Vec<i32> = (0..4).chain(nope).chain(4..8).collect();
397//! assert_eq!(nums, [0, 1, 2, 3, 4, 5, 6, 7]);
398//! ```
399//!
400//! One reason to chain iterators in this way is that a function returning
401//! `impl Iterator` must have all possible return values be of the same
402//! concrete type. Chaining an iterated [`Perhaps`] can help with that.
403//!
404//! ```
405//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
406//!     // Explicit returns to illustrate return types matching
407//!     match do_insert {
408//!         true => return (0..4).chain(Certain(42)).chain(4..8),
409//!         false => return (0..4).chain(Dubious).chain(4..8),
410//!     }
411//! }
412//! println!("{:?}", make_iter(true).collect::<Vec<_>>());
413//! println!("{:?}", make_iter(false).collect::<Vec<_>>());
414//! ```
415//!
416//! If we try to do the same thing, but using [`once()`] and [`empty()`],
417//! we can't return `impl Iterator` anymore because the concrete types of
418//! the return values differ.
419//!
420//! [`empty()`]: crate::iter::empty
421//! [`once()`]: crate::iter::once
422//!
423//! ```compile_fail,E0308
424//! # use std::iter::{empty, once};
425//! // This won't compile because all possible returns from the function
426//! // must have the same concrete type.
427//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
428//!     // Explicit returns to illustrate return types not matching
429//!     match do_insert {
430//!         true => return (0..4).chain(once(42)).chain(4..8),
431//!         false => return (0..4).chain(empty()).chain(4..8),
432//!     }
433//! }
434//! ```
435//!
436//! ## Collecting into `Perhaps`
437//!
438//! [`Perhaps`] implements the [`FromIterator`][impl-FromIterator] trait,
439//! which allows an iterator over [`Perhaps`] values to be collected into an
440//! [`Perhaps`] of a collection of each contained value of the original
441//! [`Perhaps`] values, or [`Self::Dubious`] if any of the elements was [`Dubious`].
442//!
443//! [impl-FromIterator]: Perhaps#impl-FromIterator%3CPerhaps%3CA%3E%3E-for-Perhaps%3CV%3E
444//!
445//! ```
446//! let v = [Self::Certain(2), Self::Certain(4), Dubious, Certain(8)];
447//! let res: Perhaps<Vec<_>> = v.into_iter().collect();
448//! assert_eq!(res, Dubious);
449//! let v = [Self::Certain(2), Self::Certain(4), Certain(8)];
450//! let res: Perhaps<Vec<_>> = v.into_iter().collect();
451//! assert_eq!(res, Certain(vec![2, 4, 8]));
452//! ```
453//!
454//! [`Perhaps`] also implements the [`Product`][impl-Product] and
455//! [`Sum`][impl-Sum] traits, allowing an iterator over [`Perhaps`] values
456//! to provide the [`product`][Iterator::product] and
457//! [`sum`][Iterator::sum] methods.
458//!
459//! [impl-Product]: Perhaps#impl-Product%3CPerhaps%3CU%3E%3E-for-Perhaps%3CT%3E
460//! [impl-Sum]: Perhaps#impl-Sum%3CPerhaps%3CU%3E%3E-for-Perhaps%3CT%3E
461//!
462//! ```
463//! let v = [Dubious, Self::Certain(1), Self::Certain(2), Certain(3)];
464//! let res: Perhaps<i32> = v.into_iter().sum();
465//! assert_eq!(res, Dubious);
466//! let v = [Self::Certain(1), Self::Certain(2), Certain(21)];
467//! let res: Perhaps<i32> = v.into_iter().product();
468//! assert_eq!(res, Certain(42));
469//! ```
470//!
471//! ## Modifying an [`Perhaps`] in-place
472//!
473//! These methods return a mutable reference to the contained value of an
474//! [`Perhaps<T>`]:
475//!
476//! * [`insert`] inserts a value, dropping any old contents
477//! * [`get_or_insert`] gets the current value, inserting a provided
478//!   default value if it is [`Dubious`]
479//! * [`get_or_insert_default`] gets the current value, inserting the
480//!   default value of type `T` (which must implement [`Default`]) if it is
481//!   [`Dubious`]
482//! * [`get_or_insert_with`] gets the current value, inserting a default
483//!   computed by the provided function if it is [`Dubious`]
484//!
485//! [`get_or_insert`]: Perhaps::get_or_insert
486//! [`get_or_insert_default`]: Perhaps::get_or_insert_default
487//! [`get_or_insert_with`]: Perhaps::get_or_insert_with
488//! [`insert`]: Perhaps::insert
489//!
490//! These methods transfer ownership of the contained value of an
491//! [`Perhaps`]:
492//!
493//! * [`take`] takes ownership of the contained value of an [`Perhaps`], if
494//!   any, replacing the [`Perhaps`] with [`Dubious`]
495//! * [`replace`] takes ownership of the contained value of an [`Perhaps`],
496//!   if any, replacing the [`Perhaps`] with a [`Certain`] containing the
497//!   provided value
498//!
499//! [`replace`]: Perhaps::replace
500//! [`take`]: Perhaps::take
501//!
502//! # Examples
503//!
504//! Basic pattern matching on [`Perhaps`]:
505//!
506//! ```
507//! let msg = Certain("howdy");
508//!
509//! // Take a reference to the contained string
510//! if let Certain(m) = &msg {
511//!     println!("{}", *m);
512//! }
513//!
514//! // Remove the contained string, destroying the Perhaps
515//! let unwrapped_msg = msg.unwrap_or("default message");
516//! ```
517//!
518//! Initialize a result to [`Dubious`] before a loop:
519//!
520//! ```
521//! enum Kingdom { Plant(u32, &'static str), Animal(u32, &'static str) }
522//!
523//! // A list of data to search through.
524//! let all_the_big_things = [
525//!     Kingdom::Plant(250, "redwood"),
526//!     Kingdom::Plant(230, "noble fir"),
527//!     Kingdom::Plant(229, "sugar pine"),
528//!     Kingdom::Animal(25, "blue whale"),
529//!     Kingdom::Animal(19, "fin whale"),
530//!     Kingdom::Animal(15, "north pacific right whale"),
531//! ];
532//!
533//! // We're going to search for the name of the biggest animal,
534//! // but to start with we've just got `Dubious`.
535//! let mut name_of_biggest_animal = Dubious;
536//! let mut size_of_biggest_animal = 0;
537//! for big_thing in &all_the_big_things {
538//!     match *big_thing {
539//!         Kingdom::Animal(size, name) if size > size_of_biggest_animal => {
540//!             // Now we've found the name of some big animal
541//!             size_of_biggest_animal = size;
542//!             name_of_biggest_animal = Certain(name);
543//!         }
544//!         Kingdom::Animal(..) | Kingdom::Plant(..) => ()
545//!     }
546//! }
547//!
548//! match name_of_biggest_animal {
549//!     Certain(name) => println!("the biggest animal is {name}"),
550//!     Dubious => println!("there are no animals :("),
551//! }
552//! ```
553
554use std::{
555    hint, mem,
556    ops::{Deref, DerefMut},
557};
558
559/// The `Perhaps` type. See [the module level documentation](self) for more.
560#[derive(Copy, PartialEq, PartialOrd, Eq, Debug, Hash)]
561pub enum Perhaps<T> {
562    /// No value.
563    Dubious,
564    /// Certain value of type `T`.
565    Certain(T),
566}
567
568/////////////////////////////////////////////////////////////////////////////
569// Type implementation
570/////////////////////////////////////////////////////////////////////////////
571
572impl<T> Perhaps<T> {
573    /////////////////////////////////////////////////////////////////////////
574    // Querying the contained values
575    /////////////////////////////////////////////////////////////////////////
576
577    /// Returns `true` if the option is a [`Certain`] value.
578    ///
579    /// # Examples
580    ///
581    /// ```
582    /// let x: Perhaps<u32> = Certain(2);
583    /// assert_eq!(x.is_certain(), true);
584    ///
585    /// let x: Perhaps<u32> = Dubious;
586    /// assert_eq!(x.is_certain(), false);
587    /// ```
588    #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
589    #[inline]
590    pub const fn is_certain(&self) -> bool {
591        matches!(*self, Self::Certain(_))
592    }
593
594    /// Returns `true` if the option is a [`Certain`] and the value inside of it matches a predicate.
595    ///
596    /// # Examples
597    ///
598    /// ```
599    /// let x: Perhaps<u32> = Certain(2);
600    /// assert_eq!(x.is_certain_and(|x| x > 1), true);
601    ///
602    /// let x: Perhaps<u32> = Certain(0);
603    /// assert_eq!(x.is_certain_and(|x| x > 1), false);
604    ///
605    /// let x: Perhaps<u32> = Dubious;
606    /// assert_eq!(x.is_certain_and(|x| x > 1), false);
607    /// ```
608    #[must_use]
609    #[inline]
610    pub fn is_certain_and(self, f: impl FnOnce(T) -> bool) -> bool {
611        match self {
612            Self::Dubious => false,
613            Self::Certain(x) => f(x),
614        }
615    }
616
617    /// Returns `true` if the option is a [`Dubious`] value.
618    ///
619    /// # Examples
620    ///
621    /// ```
622    /// let x: Perhaps<u32> = Certain(2);
623    /// assert_eq!(x.is_dubious(), false);
624    ///
625    /// let x: Perhaps<u32> = Dubious;
626    /// assert_eq!(x.is_dubious(), true);
627    /// ```
628    #[must_use = "if you intended to assert that this doesn't have a value, consider \
629                  wrapping this in an `assert!()` instead"]
630    #[inline]
631    pub const fn is_dubious(&self) -> bool {
632        !self.is_certain()
633    }
634
635    /////////////////////////////////////////////////////////////////////////
636    // Adapter for working with references
637    /////////////////////////////////////////////////////////////////////////
638
639    /// Converts from `&Perhaps<T>` to `Perhaps<&T>`.
640    ///
641    /// # Examples
642    ///
643    /// Calculates the length of an <code>Perhaps<[String]></code> as an <code>Perhaps<[usize]></code>
644    /// without moving the [`String`]. The [`map`] method takes the `self` argument by value,
645    /// consuming the original, so this technique uses `as_ref` to first take an `Perhaps` to a
646    /// reference to the value inside the original.
647    ///
648    /// [`map`]: Perhaps::map
649    /// [String]: ../../std/string/struct.String.html "String"
650    /// [`String`]: ../../std/string/struct.String.html "String"
651    ///
652    /// ```
653    /// let text: Perhaps<String> = Certain("Hello, world!".to_string());
654    /// // First, cast `Perhaps<String>` to `Perhaps<&String>` with `as_ref`,
655    /// // then consume *that* with `map`, leaving `text` on the stack.
656    /// let text_length: Perhaps<usize> = text.as_ref().map(|s| s.len());
657    /// println!("still can print text: {text:?}");
658    /// ```
659    #[inline]
660    pub const fn as_ref(&self) -> Perhaps<&T> {
661        match *self {
662            Self::Certain(ref x) => Perhaps::Certain(x),
663            Self::Dubious => Perhaps::Dubious,
664        }
665    }
666
667    /// Converts from `&mut Perhaps<T>` to `Perhaps<&mut T>`.
668    ///
669    /// # Examples
670    ///
671    /// ```
672    /// let mut x = Certain(2);
673    /// match x.as_mut() {
674    ///     Certain(v) => *v = 42,
675    ///     Dubious => {},
676    /// }
677    /// assert_eq!(x, Certain(42));
678    /// ```
679    #[inline]
680    pub fn as_mut(&mut self) -> Perhaps<&mut T> {
681        match *self {
682            Self::Certain(ref mut x) => Perhaps::Certain(x),
683            Self::Dubious => Perhaps::Dubious,
684        }
685    }
686
687    /////////////////////////////////////////////////////////////////////////
688    // Getting to contained values
689    /////////////////////////////////////////////////////////////////////////
690
691    /// Returns the contained [`Certain`] value, consuming the `self` value.
692    ///
693    /// # Panics
694    ///
695    /// Panics if the value is a [`Dubious`] with a custom panic message provided by
696    /// `msg`.
697    ///
698    /// # Examples
699    ///
700    /// ```
701    /// let x = Certain("value");
702    /// assert_eq!(x.expect("fruits are healthy"), "value");
703    /// ```
704    ///
705    /// ```should_panic
706    /// let x: Perhaps<&str> = Dubious;
707    /// x.expect("fruits are healthy"); // panics with `fruits are healthy`
708    /// ```
709    ///
710    /// # Recommended Message Style
711    ///
712    /// We recommend that `expect` messages are used to describe the reason you
713    /// _expect_ the `Perhaps` should be `Certain`.
714    ///
715    /// ```should_panic
716    /// # let slice: &[u8] = &[];
717    /// let item = slice.get(0)
718    ///     .expect("slice should not be empty");
719    /// ```
720    ///
721    /// **Hint**: If you're having trouble remembering how to phrase expect
722    /// error messages remember to focus on the word "should" as in "env
723    /// variable should be set by blah" or "the given binary should be available
724    /// and executable by the current user".
725    ///
726    /// For more detail on expect message styles and the reasoning behind our
727    /// recommendation please refer to the section on ["Common Message
728    /// Styles"](../../std/error/index.html#common-message-styles) in the [`std::error`](../../std/error/index.html) module docs.
729    #[inline]
730    #[track_caller]
731    pub fn expect(self, msg: &str) -> T {
732        match self {
733            Self::Certain(val) => val,
734            Self::Dubious => expect_failed(msg),
735        }
736    }
737
738    /// Returns the contained [`Certain`] value, consuming the `self` value.
739    ///
740    /// Because this function may panic, its use is generally discouraged.
741    /// Instead, prefer to use pattern matching and handle the [`Dubious`]
742    /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
743    /// [`unwrap_or_default`].
744    ///
745    /// [`unwrap_or`]: Perhaps::unwrap_or
746    /// [`unwrap_or_else`]: Perhaps::unwrap_or_else
747    /// [`unwrap_or_default`]: Perhaps::unwrap_or_default
748    ///
749    /// # Panics
750    ///
751    /// Panics if the self value equals [`Dubious`].
752    ///
753    /// # Examples
754    ///
755    /// ```
756    /// let x = Certain("air");
757    /// assert_eq!(x.unwrap(), "air");
758    /// ```
759    ///
760    /// ```should_panic
761    /// let x: Perhaps<&str> = Dubious;
762    /// assert_eq!(x.unwrap(), "air"); // fails
763    /// ```
764    #[inline(always)]
765    #[track_caller]
766    pub fn unwrap(self) -> T {
767        match self {
768            Self::Certain(val) => val,
769            Self::Dubious => unwrap_failed(),
770        }
771    }
772
773    /// Returns the contained [`Certain`] value or a provided default.
774    ///
775    /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing
776    /// the result of a function call, it is recommended to use [`unwrap_or_else`],
777    /// which is lazily evaluated.
778    ///
779    /// [`unwrap_or_else`]: Perhaps::unwrap_or_else
780    ///
781    /// # Examples
782    ///
783    /// ```
784    /// assert_eq!(Certain("car").unwrap_or("bike"), "car");
785    /// assert_eq!(Dubious.unwrap_or("bike"), "bike");
786    /// ```
787    #[inline]
788    pub fn unwrap_or(self, default: T) -> T {
789        match self {
790            Self::Certain(x) => x,
791            Self::Dubious => default,
792        }
793    }
794
795    /// Returns the contained [`Certain`] value or computes it from a closure.
796    ///
797    /// # Examples
798    ///
799    /// ```
800    /// let k = 10;
801    /// assert_eq!(Certain(4).unwrap_or_else(|| 2 * k), 4);
802    /// assert_eq!(Dubious.unwrap_or_else(|| 2 * k), 20);
803    /// ```
804    #[inline]
805    #[track_caller]
806    pub fn unwrap_or_else<F>(self, f: F) -> T
807    where
808        F: FnOnce() -> T,
809    {
810        match self {
811            Self::Certain(x) => x,
812            Self::Dubious => f(),
813        }
814    }
815
816    /// Returns the contained [`Certain`] value or a default.
817    ///
818    /// Consumes the `self` argument then, if [`Certain`], returns the contained
819    /// value, otherwise if [`Dubious`], returns the [default value] for that
820    /// type.
821    ///
822    /// # Examples
823    ///
824    /// ```
825    /// let x: Perhaps<u32> = Dubious;
826    /// let y: Perhaps<u32> = Certain(12);
827    ///
828    /// assert_eq!(x.unwrap_or_default(), 0);
829    /// assert_eq!(y.unwrap_or_default(), 12);
830    /// ```
831    ///
832    /// [default value]: Default::default
833    /// [`parse`]: str::parse
834    /// [`FromStr`]: crate::str::FromStr
835    #[inline]
836    pub fn unwrap_or_default(self) -> T
837    where
838        T: Default,
839    {
840        match self {
841            Self::Certain(x) => x,
842            Self::Dubious => T::default(),
843        }
844    }
845
846    /// Returns the contained [`Certain`] value, consuming the `self` value,
847    /// without checking that the value is not [`Dubious`].
848    ///
849    /// # Safety
850    ///
851    /// Calling this method on [`Dubious`] is *[undefined behavior]*.
852    ///
853    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
854    ///
855    /// # Examples
856    ///
857    /// ```
858    /// let x = Certain("air");
859    /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
860    /// ```
861    ///
862    /// ```no_run
863    /// let x: Perhaps<&str> = Dubious;
864    /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); // Undefined behavior!
865    /// ```
866    #[inline]
867    #[track_caller]
868    pub unsafe fn unwrap_unchecked(self) -> T {
869        match self {
870            Self::Certain(val) => val,
871            // SAFETY: the safety contract must be upheld by the caller.
872            Self::Dubious => unsafe { hint::unreachable_unchecked() },
873        }
874    }
875
876    /////////////////////////////////////////////////////////////////////////
877    // Transforming contained values
878    /////////////////////////////////////////////////////////////////////////
879
880    /// Maps an `Perhaps<T>` to `Perhaps<U>` by applying a function to a contained value (if `Certain`) or returns `Self::Dubious` (if `Dubious`).
881    ///
882    /// # Examples
883    ///
884    /// Calculates the length of an <code>Perhaps<[String]></code> as an
885    /// <code>Perhaps<[usize]></code>, consuming the original:
886    ///
887    /// [String]: ../../std/string/struct.String.html "String"
888    /// ```
889    /// let maybe_string = Certain(String::from("Hello, World!"));
890    /// // `Perhaps::map` takes self *by value*, consuming `maybe_some_string`
891    /// let maybe_len = maybe_string.map(|s| s.len());
892    /// assert_eq!(maybe_len, Certain(13));
893    ///
894    /// let x: Perhaps<&str> = Dubious;
895    /// assert_eq!(x.map(|s| s.len()), Dubious);
896    /// ```
897    #[inline]
898    pub fn map<U, F>(self, f: F) -> Perhaps<U>
899    where
900        F: FnOnce(T) -> U,
901    {
902        match self {
903            Self::Certain(x) => Perhaps::Certain(f(x)),
904            Self::Dubious => Perhaps::Dubious,
905        }
906    }
907
908    /// Calls a function with a reference to the contained value if [`Certain`].
909    ///
910    /// Returns the original option.
911    ///
912    /// # Examples
913    ///
914    /// ```
915    /// let list = vec![1, 2, 3];
916    ///
917    /// // prints "got: 2"
918    /// let x = list
919    ///     .get(1)
920    ///     .inspect(|x| println!("got: {x}"))
921    ///     .expect("list should be long enough");
922    ///
923    /// // prints nothing
924    /// list.get(5).inspect(|x| println!("got: {x}"));
925    /// ```
926    #[inline]
927    pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
928        if let Self::Certain(ref x) = self {
929            f(x);
930        }
931
932        self
933    }
934
935    /// Returns the provided default result (if dubious),
936    /// or applies a function to the contained value (if any).
937    ///
938    /// Arguments passed to `map_or` are eagerly evaluated; if you are passing
939    /// the result of a function call, it is recommended to use [`map_or_else`],
940    /// which is lazily evaluated.
941    ///
942    /// [`map_or_else`]: Perhaps::map_or_else
943    ///
944    /// # Examples
945    ///
946    /// ```
947    /// let x = Certain("foo");
948    /// assert_eq!(x.map_or(42, |v| v.len()), 3);
949    ///
950    /// let x: Perhaps<&str> = Dubious;
951    /// assert_eq!(x.map_or(42, |v| v.len()), 42);
952    /// ```
953    #[inline]
954    #[must_use = "if you don't need the returned value, use `if let` instead"]
955    pub fn map_or<U, F>(self, default: U, f: F) -> U
956    where
957        F: FnOnce(T) -> U,
958    {
959        match self {
960            Self::Certain(t) => f(t),
961            Self::Dubious => default,
962        }
963    }
964
965    /// Computes a default function result (if dubious), or
966    /// applies a different function to the contained value (if any).
967    ///
968    /// # Basic examples
969    ///
970    /// ```
971    /// let k = 21;
972    ///
973    /// let x = Certain("foo");
974    /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 3);
975    ///
976    /// let x: Perhaps<&str> = Dubious;
977    /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42);
978    /// ```
979    ///
980    /// # Handling a Result-based fallback
981    ///
982    /// A somewhat common occurrence when dealing with optional values
983    /// in combination with [`Result<T, E>`] is the case where one wants to invoke
984    /// a fallible fallback if the option is not present.  This example
985    /// parses a command line argument (if present), or the contents of a file to
986    /// an integer.  However, unlike accessing the command line argument, reading
987    /// the file is fallible, so it must be wrapped with `Ok`.
988    ///
989    /// ```no_run
990    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
991    /// let v: u64 = std::env::args()
992    ///    .nth(1)
993    ///    .map_or_else(|| std::fs::read_to_string("/etc/someconfig.conf"), Ok)?
994    ///    .parse()?;
995    /// #   Ok(())
996    /// # }
997    /// ```
998    #[inline]
999    pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
1000    where
1001        D: FnOnce() -> U,
1002        F: FnOnce(T) -> U,
1003    {
1004        match self {
1005            Self::Certain(t) => f(t),
1006            Self::Dubious => default(),
1007        }
1008    }
1009
1010    /// Transforms the `Perhaps<T>` into a [`Result<T, E>`], mapping [`Certain(v)`] to
1011    /// [`Ok(v)`] and [`Dubious`] to [`Err(err)`].
1012    ///
1013    /// Arguments passed to `ok_or` are eagerly evaluated; if you are passing the
1014    /// result of a function call, it is recommended to use [`ok_or_else`], which is
1015    /// lazily evaluated.
1016    ///
1017    /// [`Ok(v)`]: Ok
1018    /// [`Err(err)`]: Err
1019    /// [`Self::Certain(v)`]: Certain
1020    /// [`ok_or_else`]: Perhaps::ok_or_else
1021    ///
1022    /// # Examples
1023    ///
1024    /// ```
1025    /// let x = Certain("foo");
1026    /// assert_eq!(x.ok_or(0), Ok("foo"));
1027    ///
1028    /// let x: Perhaps<&str> = Dubious;
1029    /// assert_eq!(x.ok_or(0), Err(0));
1030    /// ```
1031    #[inline]
1032    pub fn ok_or<E>(self, err: E) -> Result<T, E> {
1033        match self {
1034            Self::Certain(v) => Ok(v),
1035            Self::Dubious => Err(err),
1036        }
1037    }
1038
1039    /// Transforms the `Perhaps<T>` into a [`Result<T, E>`], mapping [`Certain(v)`] to
1040    /// [`Ok(v)`] and [`Dubious`] to [`Err(err())`].
1041    ///
1042    /// [`Ok(v)`]: Ok
1043    /// [`Err(err())`]: Err
1044    /// [`Self::Certain(v)`]: Certain
1045    ///
1046    /// # Examples
1047    ///
1048    /// ```
1049    /// let x = Certain("foo");
1050    /// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
1051    ///
1052    /// let x: Perhaps<&str> = Dubious;
1053    /// assert_eq!(x.ok_or_else(|| 0), Err(0));
1054    /// ```
1055    #[inline]
1056    pub fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
1057    where
1058        F: FnOnce() -> E,
1059    {
1060        match self {
1061            Self::Certain(v) => Ok(v),
1062            Self::Dubious => Err(err()),
1063        }
1064    }
1065
1066    /// Converts from `Perhaps<T>` (or `&Perhaps<T>`) to `Perhaps<&T::Target>`.
1067    ///
1068    /// Leaves the original Perhaps in-place, creating a new one with a reference
1069    /// to the original one, additionally coercing the contents via [`Deref`].
1070    ///
1071    /// # Examples
1072    ///
1073    /// ```
1074    /// let x: Perhaps<String> = Certain("hey".to_owned());
1075    /// assert_eq!(x.as_deref(), Certain("hey"));
1076    ///
1077    /// let x: Perhaps<String> = Dubious;
1078    /// assert_eq!(x.as_deref(), Dubious);
1079    /// ```
1080    #[inline]
1081    pub fn as_deref(&self) -> Perhaps<&T::Target>
1082    where
1083        T: Deref,
1084    {
1085        match self.as_ref() {
1086            Perhaps::Certain(t) => Perhaps::Certain(t.deref()),
1087            Perhaps::Dubious => Perhaps::Dubious,
1088        }
1089    }
1090
1091    /// Converts from `Perhaps<T>` (or `&mut Perhaps<T>`) to `Perhaps<&mut T::Target>`.
1092    ///
1093    /// Leaves the original `Perhaps` in-place, creating a new one containing a mutable reference to
1094    /// the inner type's [`Deref::Target`] type.
1095    ///
1096    /// # Examples
1097    ///
1098    /// ```
1099    /// let mut x: Perhaps<String> = Certain("hey".to_owned());
1100    /// assert_eq!(x.as_deref_mut().map(|x| {
1101    ///     x.make_ascii_uppercase();
1102    ///     x
1103    /// }), Certain("HEY".to_owned().as_mut_str()));
1104    /// ```
1105    #[inline]
1106    pub fn as_deref_mut(&mut self) -> Perhaps<&mut T::Target>
1107    where
1108        T: DerefMut,
1109    {
1110        match self.as_mut() {
1111            Perhaps::Certain(t) => Perhaps::Certain(t.deref_mut()),
1112            Perhaps::Dubious => Perhaps::Dubious,
1113        }
1114    }
1115
1116    /////////////////////////////////////////////////////////////////////////
1117    // Iterator constructors
1118    /////////////////////////////////////////////////////////////////////////
1119
1120    /////////////////////////////////////////////////////////////////////////
1121    // Boolean operations on the values, eager and lazy
1122    /////////////////////////////////////////////////////////////////////////
1123
1124    /// Returns [`Self::Dubious`] if the option is [`Dubious`], otherwise returns `optb`.
1125    ///
1126    /// Arguments passed to `and` are eagerly evaluated; if you are passing the
1127    /// result of a function call, it is recommended to use [`and_then`], which is
1128    /// lazily evaluated.
1129    ///
1130    /// [`and_then`]: Perhaps::and_then
1131    ///
1132    /// # Examples
1133    ///
1134    /// ```
1135    /// let x = Certain(2);
1136    /// let y: Perhaps<&str> = Dubious;
1137    /// assert_eq!(x.and(y), Dubious);
1138    ///
1139    /// let x: Perhaps<u32> = Dubious;
1140    /// let y = Certain("foo");
1141    /// assert_eq!(x.and(y), Dubious);
1142    ///
1143    /// let x = Certain(2);
1144    /// let y = Certain("foo");
1145    /// assert_eq!(x.and(y), Certain("foo"));
1146    ///
1147    /// let x: Perhaps<u32> = Dubious;
1148    /// let y: Perhaps<&str> = Dubious;
1149    /// assert_eq!(x.and(y), Dubious);
1150    /// ```
1151    #[inline]
1152    pub fn and<U>(self, optb: Perhaps<U>) -> Perhaps<U> {
1153        match self {
1154            Self::Certain(_) => optb,
1155            Self::Dubious => Perhaps::<U>::Dubious,
1156        }
1157    }
1158
1159    /// Returns [`Self::Dubious`] if the option is [`Dubious`], otherwise calls `f` with the
1160    /// wrapped value and returns the result.
1161    ///
1162    /// Certain languages call this operation flatmap.
1163    ///
1164    /// # Examples
1165    ///
1166    /// ```
1167    /// fn sq_then_to_string(x: u32) -> Perhaps<String> {
1168    ///     x.checked_mul(x).map(|sq| sq.to_string())
1169    /// }
1170    ///
1171    /// assert_eq!(Self::Certain(2).and_then(sq_then_to_string), Certain(4.to_string()));
1172    /// assert_eq!(Certain(1_000_000).and_then(sq_then_to_string), Dubious); // overflowed!
1173    /// assert_eq!(Self::Dubious.and_then(sq_then_to_string), Dubious);
1174    /// ```
1175    ///
1176    /// Often used to chain fallible operations that may return [`Dubious`].
1177    ///
1178    /// ```
1179    /// let arr_2d = [["A0", "A1"], ["B0", "B1"]];
1180    ///
1181    /// let item_0_1 = arr_2d.get(0).and_then(|row| row.get(1));
1182    /// assert_eq!(item_0_1, Certain(&"A1"));
1183    ///
1184    /// let item_2_0 = arr_2d.get(2).and_then(|row| row.get(0));
1185    /// assert_eq!(item_2_0, Dubious);
1186    /// ```
1187    #[doc(alias = "flatmap")]
1188    #[inline]
1189    pub fn and_then<U, F>(self, f: F) -> Perhaps<U>
1190    where
1191        F: FnOnce(T) -> Perhaps<U>,
1192    {
1193        match self {
1194            Self::Certain(x) => f(x),
1195            Self::Dubious => Perhaps::Dubious,
1196        }
1197    }
1198
1199    /// Returns [`Self::Dubious`] if the option is [`Dubious`], otherwise calls `predicate`
1200    /// with the wrapped value and returns:
1201    ///
1202    /// - [`Certain(t)`] if `predicate` returns `true` (where `t` is the wrapped
1203    ///   value), and
1204    /// - [`Dubious`] if `predicate` returns `false`.
1205    ///
1206    /// This function works similar to [`Iterator::filter()`]. You can imagine
1207    /// the `Perhaps<T>` being an iterator over one or zero elements. `filter()`
1208    /// lets you decide which elements to keep.
1209    ///
1210    /// # Examples
1211    ///
1212    /// ```rust
1213    /// fn is_even(n: &i32) -> bool {
1214    ///     n % 2 == 0
1215    /// }
1216    ///
1217    /// assert_eq!(Self::Dubious.filter(is_even), Dubious);
1218    /// assert_eq!(Certain(3).filter(is_even), Dubious);
1219    /// assert_eq!(Self::Certain(4).filter(is_even), Certain(4));
1220    /// ```
1221    ///
1222    /// [`Self::Certain(t)`]: Certain
1223    #[inline]
1224    pub fn filter<P>(self, predicate: P) -> Self
1225    where
1226        P: FnOnce(&T) -> bool,
1227    {
1228        if let Self::Certain(x) = self {
1229            if predicate(&x) {
1230                return Self::Certain(x);
1231            }
1232        }
1233        Self::Dubious
1234    }
1235
1236    /// Returns the option if it contains a value, otherwise returns `optb`.
1237    ///
1238    /// Arguments passed to `or` are eagerly evaluated; if you are passing the
1239    /// result of a function call, it is recommended to use [`or_else`], which is
1240    /// lazily evaluated.
1241    ///
1242    /// [`or_else`]: Perhaps::or_else
1243    ///
1244    /// # Examples
1245    ///
1246    /// ```
1247    /// let x = Certain(2);
1248    /// let y = Dubious;
1249    /// assert_eq!(x.or(y), Certain(2));
1250    ///
1251    /// let x = Dubious;
1252    /// let y = Certain(100);
1253    /// assert_eq!(x.or(y), Certain(100));
1254    ///
1255    /// let x = Certain(2);
1256    /// let y = Certain(100);
1257    /// assert_eq!(x.or(y), Certain(2));
1258    ///
1259    /// let x: Perhaps<u32> = Dubious;
1260    /// let y = Dubious;
1261    /// assert_eq!(x.or(y), Dubious);
1262    /// ```
1263    #[inline]
1264    pub fn or(self, optb: Perhaps<T>) -> Perhaps<T> {
1265        match self {
1266            x @ Self::Certain(_) => x,
1267            Self::Dubious => optb,
1268        }
1269    }
1270
1271    /// Returns the option if it contains a value, otherwise calls `f` and
1272    /// returns the result.
1273    ///
1274    /// # Examples
1275    ///
1276    /// ```
1277    /// fn nobody() -> Perhaps<&'static str> { Dubious }
1278    /// fn vikings() -> Perhaps<&'static str> { Certain("vikings") }
1279    ///
1280    /// assert_eq!(Self::Certain("barbarians").or_else(vikings), Certain("barbarians"));
1281    /// assert_eq!(Dubious.or_else(vikings), Certain("vikings"));
1282    /// assert_eq!(Self::Dubious.or_else(nobody), Dubious);
1283    /// ```
1284    #[inline]
1285    pub fn or_else<F>(self, f: F) -> Perhaps<T>
1286    where
1287        F: FnOnce() -> Perhaps<T>,
1288    {
1289        match self {
1290            x @ Self::Certain(_) => x,
1291            Self::Dubious => f(),
1292        }
1293    }
1294
1295    /// Returns [`Self::Certain`] if exactly one of `self`, `optb` is [`Certain`], otherwise returns [`Dubious`].
1296    ///
1297    /// # Examples
1298    ///
1299    /// ```
1300    /// let x = Certain(2);
1301    /// let y: Perhaps<u32> = Dubious;
1302    /// assert_eq!(x.xor(y), Certain(2));
1303    ///
1304    /// let x: Perhaps<u32> = Dubious;
1305    /// let y = Certain(2);
1306    /// assert_eq!(x.xor(y), Certain(2));
1307    ///
1308    /// let x = Certain(2);
1309    /// let y = Certain(2);
1310    /// assert_eq!(x.xor(y), Dubious);
1311    ///
1312    /// let x: Perhaps<u32> = Dubious;
1313    /// let y: Perhaps<u32> = Dubious;
1314    /// assert_eq!(x.xor(y), Dubious);
1315    /// ```
1316    #[inline]
1317    pub fn xor(self, optb: Perhaps<T>) -> Perhaps<T> {
1318        match (self, optb) {
1319            (a @ Self::Certain(_), Self::Dubious) => a,
1320            (Self::Dubious, b @ Self::Certain(_)) => b,
1321            _ => Self::Dubious,
1322        }
1323    }
1324
1325    /////////////////////////////////////////////////////////////////////////
1326    // Entry-like operations to insert a value and return a reference
1327    /////////////////////////////////////////////////////////////////////////
1328
1329    /// Inserts `value` into the option, then returns a mutable reference to it.
1330    ///
1331    /// If the option already contains a value, the old value is dropped.
1332    ///
1333    /// See also [`Perhaps::get_or_insert`], which doesn't update the value if
1334    /// the option already contains [`Certain`].
1335    ///
1336    /// # Example
1337    ///
1338    /// ```
1339    /// let mut opt = Dubious;
1340    /// let val = opt.insert(1);
1341    /// assert_eq!(*val, 1);
1342    /// assert_eq!(opt.unwrap(), 1);
1343    /// let val = opt.insert(2);
1344    /// assert_eq!(*val, 2);
1345    /// *val = 3;
1346    /// assert_eq!(opt.unwrap(), 3);
1347    /// ```
1348    #[must_use = "if you intended to set a value, consider assignment instead"]
1349    #[inline]
1350    pub fn insert(&mut self, value: T) -> &mut T {
1351        *self = Self::Certain(value);
1352
1353        // SAFETY: the code above just filled the option
1354        unsafe { self.as_mut().unwrap_unchecked() }
1355    }
1356
1357    /// Inserts `value` into the option if it is [`Dubious`], then
1358    /// returns a mutable reference to the contained value.
1359    ///
1360    /// See also [`Perhaps::insert`], which updates the value even if
1361    /// the option already contains [`Certain`].
1362    ///
1363    /// # Examples
1364    ///
1365    /// ```
1366    /// let mut x = Dubious;
1367    ///
1368    /// {
1369    ///     let y: &mut u32 = x.get_or_insert(5);
1370    ///     assert_eq!(y, &5);
1371    ///
1372    ///     *y = 7;
1373    /// }
1374    ///
1375    /// assert_eq!(x, Certain(7));
1376    /// ```
1377    #[inline]
1378    pub fn get_or_insert(&mut self, value: T) -> &mut T {
1379        if let Self::Dubious = *self {
1380            *self = Self::Certain(value);
1381        }
1382
1383        // SAFETY: a `Self::Dubious` variant for `self` would have been replaced by a `Self::Certain`
1384        // variant in the code above.
1385        unsafe { self.as_mut().unwrap_unchecked() }
1386    }
1387
1388    /// Inserts a value computed from `f` into the option if it is [`Dubious`],
1389    /// then returns a mutable reference to the contained value.
1390    ///
1391    /// # Examples
1392    ///
1393    /// ```
1394    /// let mut x = Dubious;
1395    ///
1396    /// {
1397    ///     let y: &mut u32 = x.get_or_insert_with(|| 5);
1398    ///     assert_eq!(y, &5);
1399    ///
1400    ///     *y = 7;
1401    /// }
1402    ///
1403    /// assert_eq!(x, Certain(7));
1404    /// ```
1405    #[inline]
1406    pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
1407    where
1408        F: FnOnce() -> T,
1409    {
1410        if let Self::Dubious = self {
1411            *self = Self::Certain(f());
1412        }
1413
1414        // SAFETY: a `Self::Dubious` variant for `self` would have been replaced by a `Self::Certain`
1415        // variant in the code above.
1416        unsafe { self.as_mut().unwrap_unchecked() }
1417    }
1418
1419    /////////////////////////////////////////////////////////////////////////
1420    // Misc
1421    /////////////////////////////////////////////////////////////////////////
1422
1423    /// Takes the value out of the option, leaving a [`Dubious`] in its place.
1424    ///
1425    /// # Examples
1426    ///
1427    /// ```
1428    /// let mut x = Certain(2);
1429    /// let y = x.take();
1430    /// assert_eq!(x, Dubious);
1431    /// assert_eq!(y, Certain(2));
1432    ///
1433    /// let mut x: Perhaps<u32> = Dubious;
1434    /// let y = x.take();
1435    /// assert_eq!(x, Dubious);
1436    /// assert_eq!(y, Dubious);
1437    /// ```
1438    #[inline]
1439    pub fn take(&mut self) -> Perhaps<T> {
1440        // FIXME replace `mem::replace` by `mem::take` when the latter is const ready
1441        mem::replace(self, Self::Dubious)
1442    }
1443
1444    /// Replaces the actual value in the option by the value given in parameter,
1445    /// returning the old value if present,
1446    /// leaving a [`Certain`] in its place without deinitializing either one.
1447    ///
1448    /// # Examples
1449    ///
1450    /// ```
1451    /// let mut x = Certain(2);
1452    /// let old = x.replace(5);
1453    /// assert_eq!(x, Certain(5));
1454    /// assert_eq!(old, Certain(2));
1455    ///
1456    /// let mut x = Dubious;
1457    /// let old = x.replace(3);
1458    /// assert_eq!(x, Certain(3));
1459    /// assert_eq!(old, Dubious);
1460    /// ```
1461    #[inline]
1462    pub fn replace(&mut self, value: T) -> Perhaps<T> {
1463        mem::replace(self, Self::Certain(value))
1464    }
1465
1466    /// Zips `self` with another `Perhaps`.
1467    ///
1468    /// If `self` is `Self::Certain(s)` and `other` is `Self::Certain(o)`, this method returns `Certain((s, o))`.
1469    /// Otherwise, `Dubious` is returned.
1470    ///
1471    /// # Examples
1472    ///
1473    /// ```
1474    /// let x = Certain(1);
1475    /// let y = Certain("hi");
1476    /// let z = Dubious::<u8>;
1477    ///
1478    /// assert_eq!(x.zip(y), Certain((1, "hi")));
1479    /// assert_eq!(x.zip(z), Dubious);
1480    /// ```
1481    pub fn zip<U>(self, other: Perhaps<U>) -> Perhaps<(T, U)> {
1482        match (self, other) {
1483            (Self::Certain(a), Perhaps::Certain(b)) => Perhaps::Certain((a, b)),
1484            _ => Perhaps::Dubious,
1485        }
1486    }
1487}
1488
1489impl<T, U> Perhaps<(T, U)> {
1490    /// Unzips an option containing a tuple of two options.
1491    ///
1492    /// If `self` is `Self::Certain((a, b))` this method returns `(Self::Certain(a), Certain(b))`.
1493    /// Otherwise, `(Self::Dubious, Dubious)` is returned.
1494    ///
1495    /// # Examples
1496    ///
1497    /// ```
1498    /// let x = Certain((1, "hi"));
1499    /// let y = Dubious::<(u8, u32)>;
1500    ///
1501    /// assert_eq!(x.unzip(), (Self::Certain(1), Certain("hi")));
1502    /// assert_eq!(y.unzip(), (Self::Dubious, Dubious));
1503    /// ```
1504    #[inline]
1505    pub fn unzip(self) -> (Perhaps<T>, Perhaps<U>) {
1506        match self {
1507            Self::Certain((a, b)) => (Perhaps::Certain(a), Perhaps::Certain(b)),
1508            Self::Dubious => (Perhaps::Dubious, Perhaps::Dubious),
1509        }
1510    }
1511}
1512
1513impl<T> Perhaps<&T> {
1514    /// Maps an `Perhaps<&T>` to an `Perhaps<T>` by copying the contents of the
1515    /// option.
1516    ///
1517    /// # Examples
1518    ///
1519    /// ```
1520    /// let x = 12;
1521    /// let opt_x = Certain(&x);
1522    /// assert_eq!(opt_x, Certain(&12));
1523    /// let copied = opt_x.copied();
1524    /// assert_eq!(copied, Certain(12));
1525    /// ```
1526    #[must_use = "`self` will be dropped if the result is not used"]
1527    pub const fn copied(self) -> Perhaps<T>
1528    where
1529        T: Copy,
1530    {
1531        // FIXME: this implementation, which sidesteps using `Perhaps::map` since it's not const
1532        // ready yet, should be reverted when possible to avoid code repetition
1533        match self {
1534            Self::Certain(&v) => Perhaps::Certain(v),
1535            Self::Dubious => Perhaps::Dubious,
1536        }
1537    }
1538
1539    /// Maps an `Perhaps<&T>` to an `Perhaps<T>` by cloning the contents of the
1540    /// option.
1541    ///
1542    /// # Examples
1543    ///
1544    /// ```
1545    /// let x = 12;
1546    /// let opt_x = Certain(&x);
1547    /// assert_eq!(opt_x, Certain(&12));
1548    /// let cloned = opt_x.cloned();
1549    /// assert_eq!(cloned, Certain(12));
1550    /// ```
1551    #[must_use = "`self` will be dropped if the result is not used"]
1552    pub fn cloned(self) -> Perhaps<T>
1553    where
1554        T: Clone,
1555    {
1556        match self {
1557            Self::Certain(t) => Perhaps::Certain(t.clone()),
1558            Self::Dubious => Perhaps::Dubious,
1559        }
1560    }
1561}
1562
1563impl<T> Perhaps<&mut T> {
1564    /// Maps an `Perhaps<&mut T>` to an `Perhaps<T>` by copying the contents of the
1565    /// option.
1566    ///
1567    /// # Examples
1568    ///
1569    /// ```
1570    /// let mut x = 12;
1571    /// let opt_x = Certain(&mut x);
1572    /// assert_eq!(opt_x, Certain(&mut 12));
1573    /// let copied = opt_x.copied();
1574    /// assert_eq!(copied, Certain(12));
1575    /// ```
1576    #[must_use = "`self` will be dropped if the result is not used"]
1577    pub fn copied(self) -> Perhaps<T>
1578    where
1579        T: Copy,
1580    {
1581        match self {
1582            Self::Certain(&mut t) => Perhaps::Certain(t),
1583            Self::Dubious => Perhaps::Dubious,
1584        }
1585    }
1586
1587    /// Maps an `Perhaps<&mut T>` to an `Perhaps<T>` by cloning the contents of the
1588    /// option.
1589    ///
1590    /// # Examples
1591    ///
1592    /// ```
1593    /// let mut x = 12;
1594    /// let opt_x = Certain(&mut x);
1595    /// assert_eq!(opt_x, Certain(&mut 12));
1596    /// let cloned = opt_x.cloned();
1597    /// assert_eq!(cloned, Certain(12));
1598    /// ```
1599    #[must_use = "`self` will be dropped if the result is not used"]
1600    pub fn cloned(self) -> Perhaps<T>
1601    where
1602        T: Clone,
1603    {
1604        match self {
1605            Self::Certain(t) => Perhaps::Certain(t.clone()),
1606            Self::Dubious => Perhaps::Dubious,
1607        }
1608    }
1609}
1610
1611impl<T, E> Perhaps<Result<T, E>> {
1612    /// Transposes an `Perhaps` of a [`Result`] into a [`Result`] of an `Perhaps`.
1613    ///
1614    /// [`Self::Dubious`] will be mapped to <code>[Ok]\([Dubious])</code>.
1615    /// <code>[Self::Certain]\([Ok]\(\_))</code> and <code>[Certain]\([Err]\(\_))</code> will be mapped to
1616    /// <code>[Ok]\([Certain]\(\_))</code> and <code>[Err]\(\_)</code>.
1617    ///
1618    /// # Examples
1619    ///
1620    /// ```
1621    /// #[derive(Debug, Eq, PartialEq)]
1622    /// struct SomeErr;
1623    ///
1624    /// let x: Result<Perhaps<i32>, SomeErr> = Ok(Certain(5));
1625    /// let y: Perhaps<Result<i32, SomeErr>> = Certain(Ok(5));
1626    /// assert_eq!(x, y.transpose());
1627    /// ```
1628    #[inline]
1629    pub fn transpose(self) -> Result<Perhaps<T>, E> {
1630        match self {
1631            Self::Certain(Ok(x)) => Ok(Perhaps::Certain(x)),
1632            Self::Certain(Err(e)) => Err(e),
1633            Self::Dubious => Ok(Perhaps::Dubious),
1634        }
1635    }
1636}
1637
1638#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
1639#[cfg_attr(feature = "panic_immediate_abort", inline)]
1640#[cold]
1641#[track_caller]
1642const fn unwrap_failed() -> ! {
1643    panic!("called `Perhaps::unwrap()` on a `Self::Dubious` value")
1644}
1645
1646// This is a separate function to reduce the code size of .expect() itself.
1647#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
1648#[cfg_attr(feature = "panic_immediate_abort", inline)]
1649#[cold]
1650#[track_caller]
1651const fn expect_failed(msg: &str) -> ! {
1652    panic!("{}", msg);
1653}
1654
1655/////////////////////////////////////////////////////////////////////////////
1656// Trait implementations
1657/////////////////////////////////////////////////////////////////////////////
1658
1659impl<T> Clone for Perhaps<T>
1660where
1661    T: Clone,
1662{
1663    #[inline]
1664    fn clone(&self) -> Self {
1665        match self {
1666            Self::Certain(x) => Self::Certain(x.clone()),
1667            Self::Dubious => Self::Dubious,
1668        }
1669    }
1670
1671    #[inline]
1672    fn clone_from(&mut self, source: &Self) {
1673        match (self, source) {
1674            (Self::Certain(to), Self::Certain(from)) => to.clone_from(from),
1675            (to, from) => *to = from.clone(),
1676        }
1677    }
1678}
1679
1680impl<T> Default for Perhaps<T> {
1681    /// Returns [`Self::Dubious`][Perhaps::Dubious].
1682    ///
1683    /// # Examples
1684    ///
1685    /// ```
1686    /// let opt: Perhaps<u32> = Perhaps::default();
1687    /// assert!(opt.is_dubious());
1688    /// ```
1689    #[inline]
1690    fn default() -> Perhaps<T> {
1691        Self::Dubious
1692    }
1693}
1694
1695impl<T> From<T> for Perhaps<T> {
1696    /// Moves `val` into a new [`Certain`].
1697    ///
1698    /// # Examples
1699    ///
1700    /// ```
1701    /// let o: Perhaps<u8> = Perhaps::from(67);
1702    ///
1703    /// assert_eq!(Certain(67), o);
1704    /// ```
1705    fn from(val: T) -> Perhaps<T> {
1706        Self::Certain(val)
1707    }
1708}
1709
1710impl<'a, T> From<&'a Perhaps<T>> for Perhaps<&'a T> {
1711    /// Converts from `&Perhaps<T>` to `Perhaps<&T>`.
1712    ///
1713    /// # Examples
1714    ///
1715    /// Converts an <code>[Perhaps]<[String]></code> into an <code>[Perhaps]<[usize]></code>, preserving
1716    /// the original. The [`map`] method takes the `self` argument by value, consuming the original,
1717    /// so this technique uses `from` to first take an [`Perhaps`] to a reference
1718    /// to the value inside the original.
1719    ///
1720    /// [`map`]: Perhaps::map
1721    /// [String]: ../../std/string/struct.String.html "String"
1722    ///
1723    /// ```
1724    /// let s: Perhaps<String> = Certain(String::from("Hello, Rustaceans!"));
1725    /// let o: Perhaps<usize> = Perhaps::from(&s).map(|ss: &String| ss.len());
1726    ///
1727    /// println!("Can still print s: {s:?}");
1728    ///
1729    /// assert_eq!(o, Certain(18));
1730    /// ```
1731    fn from(o: &'a Perhaps<T>) -> Perhaps<&'a T> {
1732        o.as_ref()
1733    }
1734}
1735
1736impl<'a, T> From<&'a mut Perhaps<T>> for Perhaps<&'a mut T> {
1737    /// Converts from `&mut Perhaps<T>` to `Perhaps<&mut T>`
1738    ///
1739    /// # Examples
1740    ///
1741    /// ```
1742    /// let mut s = Certain(String::from("Hello"));
1743    /// let o: Perhaps<&mut String> = Perhaps::from(&mut s);
1744    ///
1745    /// match o {
1746    ///     Certain(t) => *t = String::from("Hello, Rustaceans!"),
1747    ///     Dubious => (),
1748    /// }
1749    ///
1750    /// assert_eq!(s, Certain(String::from("Hello, Rustaceans!")));
1751    /// ```
1752    fn from(o: &'a mut Perhaps<T>) -> Perhaps<&'a mut T> {
1753        o.as_mut()
1754    }
1755}
1756
1757impl<T> Perhaps<Perhaps<T>> {
1758    /// Converts from `Perhaps<Perhaps<T>>` to `Perhaps<T>`.
1759    ///
1760    /// # Examples
1761    ///
1762    /// Basic usage:
1763    ///
1764    /// ```
1765    /// let x: Perhaps<Perhaps<u32>> = Self::Certain(Certain(6));
1766    /// assert_eq!(Certain(6), x.flatten());
1767    ///
1768    /// let x: Perhaps<Perhaps<u32>> = Certain(Dubious);
1769    /// assert_eq!(Dubious, x.flatten());
1770    ///
1771    /// let x: Perhaps<Perhaps<u32>> = Dubious;
1772    /// assert_eq!(Dubious, x.flatten());
1773    /// ```
1774    ///
1775    /// Flattening only removes one level of nesting at a time:
1776    ///
1777    /// ```
1778    /// let x: Perhaps<Perhaps<Perhaps<u32>>> = Self::Certain(Self::Certain(Certain(6)));
1779    /// assert_eq!(Self::Certain(Certain(6)), x.flatten());
1780    /// assert_eq!(Certain(6), x.flatten().flatten());
1781    /// ```
1782    #[inline]
1783    pub fn flatten(self) -> Perhaps<T> {
1784        match self {
1785            Self::Certain(inner) => inner,
1786            Self::Dubious => Perhaps::Dubious,
1787        }
1788    }
1789}