Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create method overview docs for core::option and core::result #86211

Merged
merged 12 commits into from
Jul 14, 2021
206 changes: 203 additions & 3 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
//! the optional owned box, [`Option`]`<`[`Box<T>`]`>`.
//!
//! The following example uses [`Option`] to create an optional box of
//! [`i32`]. Notice that in order to use the inner [`i32`] value first, the
//! `check_optional` function needs to use pattern matching to
//! [`i32`]. Notice that in order to use the inner [`i32`] value, the
//! `check_optional` function first needs to use pattern matching to
//! determine whether the box has a value (i.e., it is [`Some(...)`][`Some`]) or
//! not ([`None`]).
//!
Expand Down Expand Up @@ -90,6 +90,206 @@
//! from `Some::<T>(_)` to `T` (but transmuting `None::<T>` to `T`
//! is undefined behaviour).
//!
//! # Method overview
//!
//! In addition to working with pattern matching, [`Option`] provides a wide
//! variety of different methods.
//!
//! ## Querying the variant
//!
//! The [`is_some`] and [`is_none`] methods return [`true`] if the [`Option`]
//! is [`Some`] or [`None`], respectively.
//!
//! [`is_some`]: Option::is_some
//! [`is_none`]: Option::is_none
//!
//! ## Adapters for working with references
//!
//! * [`as_ref`] converts from `&Option<T>` to `Option<&T>`
//! * [`as_mut`] converts from `&mut Option<T>` to `Option<&mut T>`
//! * [`as_deref`] converts from `&Option<T>` to `Option<&T::Target>`
//! * [`as_deref_mut`] converts from `&mut Option<T>` to `Option<&mut T::Target>`
//! * [`as_pin_ref`] converts from [`&Pin`]`<Option<T>>` to `Option<`[`Pin`]`<&T>>`
tlyu marked this conversation as resolved.
Show resolved Hide resolved
//! * [`as_pin_mut`] converts from [`&mut Pin`]`<Option<T>>` to `Option<`[`Pin`]`<&mut T>>`
//!
//! [`&mut Pin`]: crate::pin::Pin
//! [`&Pin`]: crate::pin::Pin
//! [`as_deref`]: Option::as_deref
//! [`as_deref_mut`]: Option::as_deref_mut
//! [`as_mut`]: Option::as_mut
//! [`as_pin_ref`]: Option::as_pin_ref
//! [`as_pin_mut`]: Option::as_pin_mut
//! [`as_ref`]: Option::as_ref
//! [`Pin`]: crate::pin::Pin
//!
//! ## Extracting the contained value
//!
//! These methods extract the contained value in an [`Option`] when it is
//! the [`Some`] variant. If the [`Option`] is [`None`]:
//!
//! * [`expect`] panics with a provided custom message
//! * [`unwrap`] panics with a generic message
//! * [`unwrap_or`] returns the provided default value
//! * [`unwrap_or_default`] returns the default value of the type `T`
//! (which must implement the [`Default`] trait)
//! * [`unwrap_or_else`] evaluates a provided function
tlyu marked this conversation as resolved.
Show resolved Hide resolved
//!
//! [`Default`]: crate::default::Default
//! [`expect`]: Option::expect
//! [`unwrap`]: Option::unwrap
//! [`unwrap_or`]: Option::unwrap_or
//! [`unwrap_or_default`]: Option::unwrap_or_default
//! [`unwrap_or_else`]: Option::unwrap_or_else
//!
//! ## Transforming contained values
//!
//! * [`map`] transforms [`Some<T>`] to [`Some<U>`] using the provided
//! function
//! * [`map_or`] transforms [`Some<T>`] to a value of `U` using the
//! provided function, or transforms [`None`] to a provided default value
//! of `U`
//! * [`map_or_else`] transforms [`Some<T>`] to a value of `U` using the
//! provided function, or transforms [`None`] to a value of `U` using
//! another provided function
//! * [`ok_or`] transforms [`Some(v)`] to [`Ok(v)`], and [`None`] to
//! [`Err(err)`] using the provided default `err` value
//! * [`ok_or_else`] transforms [`Some(v)`] to [`Ok(v)`], and [`None`] to
//! a value of [`Err<E>`] using the provided function
//!
//! [`Err(err)`]: Err
tlyu marked this conversation as resolved.
Show resolved Hide resolved
//! [`map`]: Option::map
//! [`map_or`]: Option::map_or
//! [`map_or_else`]: Option::map_or_else
//! [`Ok(v)`]: Ok
//! [`ok_or`]: Option::ok_or
//! [`ok_or_else`]: Option::ok_or_else
//! [`Some(v)`]: Some
//!
//! ## Boolean operators
//!
//! These methods treat the [`Option`] as a boolean value, where [`Some`]
//! acts like [`true`] and [`None`] acts like [`false`]. There are two
//! categories of these methods: ones that take an [`Option`] as input, and
//! ones that take a function as input (to be lazily evaluated).
//!
//! The [`and`], [`or`], and [`xor`] methods take another [`Option`] as
//! input, and produce an [`Option`] as output. Only the [`and`] method can
//! produce an [`Option<U>`] value having a different inner type `U` than
//! [`Option<T>`].
yaahc marked this conversation as resolved.
Show resolved Hide resolved
//!
//! | method | self | input | output |
//! |---------|-----------|-----------|-----------|
//! | [`and`] | `None` | (ignored) | `None` |
//! | [`and`] | `Some(x)` | `None` | `None` |
//! | [`and`] | `Some(x)` | `Some(y)` | `Some(y)` |
//! | [`or`] | `None` | `None` | `None` |
//! | [`or`] | `None` | `Some(y)` | `Some(y)` |
tlyu marked this conversation as resolved.
Show resolved Hide resolved
//! | [`or`] | `Some(x)` | (ignored) | `Some(x)` |
//! | [`xor`] | `None` | `None` | `None` |
//! | [`xor`] | `None` | `Some(y)` | `Some(y)` |
//! | [`xor`] | `Some(x)` | `None` | `Some(x)` |
//! | [`xor`] | `Some(x)` | `Some(y)` | `None` |
//!
//! The [`and_then`], [`filter`], and [`or_else`] methods take a function
//! as input, and only evaluate the function when they need to produce a
//! new value. [`and_then`] and [`or_else`] take a function that produces
//! another [`Option`] value, while [`filter`] takes a predicate that is
//! used to decide whether to pass the [`Some`] value through. Only the
//! [`and_then`] method can produce an [`Option<U>`] value having a
//! different inner type `U` than [`Option<T>`].
//!
//! | method | self | function input | function result | output |
//! |--------------|-----------|----------------|-----------------|-----------|
//! | [`and_then`] | `None` | (not provided) | (not evaluated) | `None` |
//! | [`and_then`] | `Some(x)` | `x` | `None` | `None` |
//! | [`and_then`] | `Some(x)` | `x` | `Some(y)` | `Some(y)` |
//! | [`filter`] | `None` | (not provided) | (not evaluated) | `None` |
//! | [`filter`] | `Some(x)` | `x` | `false` | `None` |
//! | [`filter`] | `Some(x)` | `x` | `true` | `Some(x)` |
//! | [`or_else`] | `None` | (not provided) | `None` | `None` |
//! | [`or_else`] | `None` | (not provided) | `Some(y)` | `Some(y)` |
//! | [`or_else`] | `Some(x)` | (not provided) | (not evaluated) | `Some(x)` |
//!
//! [`and`]: Option::and
//! [`and_then`]: Option::and_then
//! [`filter`]: Option::filter
//! [`or`]: Option::or
//! [`or_else`]: Option::or_else
//! [`xor`]: Option::xor
//!
//! ## Iterators
//!
//! An [`Option`] can be iterated over. This can be helpful if you need an
//! iterator that is conditionally empty. The iterator will either produce
//! a single value (when the [`Option`] is [`Some`]), or produce no values
//! (when the [`Option`] is [`None`]). For example, [`into_iter`] acts like
//! [`once(v)`] if the [`Option`] is [`Some(v)`], and like [`empty()`] if
//! the [`Option`] is [`None`].
//!
//! Iterators over [`Option`] come in three types:
//!
//! * [`into_iter`] consumes the [`Option`] and produces the contained
//! value
//! * [`iter`] produces an immutable reference of type `&T` to the
//! contained value
//! * [`iter_mut`] produces a mutable reference of type `&mut T` to the
//! contained value
yaahc marked this conversation as resolved.
Show resolved Hide resolved
//!
//! [`Option`] implements the [`FromIterator`] trait, which allows an
//! iterator over [`Option`] values to be collected into an [`Option`] of a
//! collection of each contained value of the original [`Option`] values,
//! or [`None`] if any of the elements was [`None`].
tlyu marked this conversation as resolved.
Show resolved Hide resolved
//!
//! [`empty()`]: crate::iter::empty
//! [`FromIterator`]: Option#impl-FromIterator%3COption%3CA%3E%3E
//! [`into_iter`]: Option::into_iter
//! [`iter`]: Option::iter
//! [`iter_mut`]: Option::iter_mut
//! [`once(v)`]: crate::iter::once
//! [`Some(v)`]: Some
//!
//! An iterator over [`Option`] can be useful when chaining iterators:
//!
//! ```
//! let yep = Some(42);
//! let nope = None;
//! let nums: Vec<i32> = (0..4).chain(yep.into_iter()).chain(4..8).collect();
//! assert_eq!(nums, [0, 1, 2, 3, 42, 4, 5, 6, 7]);
//! let nums: Vec<i32> = (0..4).chain(nope.into_iter()).chain(4..8).collect();
//! assert_eq!(nums, [0, 1, 2, 3, 4, 5, 6, 7]);
//! ```
//!
//! One reason to chain iterators in this way is that a function returning
//! `impl Iterator` must have all possible return values be of the same
//! concrete type. Chaining an iterated [`Option`] can help with that.
//!
//! ```
//! let yep = Some(42);
//! let nope = None;
//!
//! fn make_iter(opt: Option<i32>) -> impl Iterator<Item = i32> {
//! (0..4).chain(opt.into_iter()).chain(4..8)
//! }
//! println!("{:?}", make_iter(yep).collect::<Vec<_>>());
//! println!("{:?}", make_iter(nope).collect::<Vec<_>>());
//! ```
//!
//! If we try to do the same thing, but using pattern matching, we can't
//! return `impl Iterator` anymore because the concrete types of the return
//! values differ.
//!
//! ```compile_fail,E0308
//! # use std::iter::{empty, once};
//! // This won't compile because all possible returns from the function
//! // must have the same concrete type.
//! fn make_iter(opt: Option<i32>) -> impl Iterator<Item = i32> {
//! match opt {
//! Some(x) => return (0..4).chain(once(x)).chain(4..8),
//! None => return (0..4).chain(empty()).chain(4..8)
tlyu marked this conversation as resolved.
Show resolved Hide resolved
//! }
//! }
//! ```
//!
//! # Examples
//!
//! Basic pattern matching on [`Option`]:
Expand Down Expand Up @@ -1350,7 +1550,7 @@ impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
///
/// Converts an `Option<`[`String`]`>` into an `Option<`[`usize`]`>`, preserving the original.
/// The [`map`] method takes the `self` argument by value, consuming the original,
/// so this technique uses `as_ref` to first take an `Option` to a reference
/// so this technique uses `from` to first take an `Option` to a reference
/// to the value inside the original.
///
/// [`map`]: Option::map
Expand Down
42 changes: 42 additions & 0 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,48 @@
//! [`Ok(T)`]: Ok
//! [`Err(E)`]: Err
//! [`io::Error`]: ../../std/io/struct.Error.html
//!
//! # Method overview
//!
//! ## Boolean operators
//!
//! These methods treat the [`Result`] as a boolean value, where [`Ok`]
//! acts like [`true`] and [`Err`] acts like [`false`]. There are two
//! categories of these methods: ones that take a [`Result`] as input, and
//! ones that take a function as input (to be lazily evaluated).
//!
//! The [`and`] and [`or`] methods take another [`Result`] as input, and
//! produce an [`Result`] as output. Only the [`and`] method can produce a
//! [`Result<U, E>`] value having a different inner type `U` than
//! [`Result<T, E>`].
//!
//! | method | self | input | output |
//! |---------|----------|-----------|----------|
//! | [`and`] | `Err(e)` | (ignored) | `Err(e)` |
//! | [`and`] | `Ok(x)` | `Err(d)` | `Err(d)` |
//! | [`and`] | `Ok(x)` | `Ok(y)` | `Ok(y)` |
//! | [`or`] | `Err(e)` | `Err(d)` | `Err(d)` |
//! | [`or`] | `Err(e)` | `Ok(y)` | `Ok(y)` |
//! | [`or`] | `Ok(x)` | (ignored) | `Ok(x)` |
//!
//! The [`and_then`] and [`or_else`] methods take a function as input, and
//! only evaluate the function when they need to produce a new value. Only
//! the [`and_then`] method can produce an [`Result<U, E>`] value having a
//! different inner type `U` than [`Result<T, E>`].
tlyu marked this conversation as resolved.
Show resolved Hide resolved
//!
//! | method | self | function input | function result | output |
//! |--------------|----------|----------------|-----------------|----------|
//! | [`and_then`] | `Err(e)` | (not provided) | (not evaluated) | `Err(e)` |
//! | [`and_then`] | `Ok(x)` | `x` | `Err(d)` | `Err(d)` |
//! | [`and_then`] | `Ok(x)` | `x` | `Ok(y)` | `Ok(y)` |
//! | [`or_else`] | `Err(e)` | `e` | `Err(d)` | `Err(d)` |
//! | [`or_else`] | `Err(e)` | `e` | `Ok(y)` | `Ok(y)` |
//! | [`or_else`] | `Ok(x)` | (not provided) | (not evaluated) | `Ok(x)` |
//!
//! [`and`]: Result::and
//! [`and_then`]: Result::and_then
//! [`or`]: Result::or
//! [`or_else`]: Result::or_else

#![stable(feature = "rust1", since = "1.0.0")]

Expand Down