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}