Auto merge of #86211 - tlyu:option-result-overviews, r=joshtriplett

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

The `Option` and `Result` types have large lists of methods. They each could use an overview page of methods grouped by category. These proposed overviews include "truth tables" for the underappreciated boolean operators/combinators of these types. The methods are already somewhat categorized in the source, but some logical groupings are broken up by the necessities of putting related methods in different `impl` blocks, for example.

This is based on #86209, but those are small changes and unlikely to conflict.
This commit is contained in:
bors 2021-07-14 05:10:57 +00:00
commit a08f25a7ef
2 changed files with 583 additions and 5 deletions

View File

@ -49,6 +49,8 @@
//! no "null" references. Instead, Rust has *optional* pointers, like
//! the optional owned box, [`Option`]`<`[`Box<T>`]`>`.
//!
//! [`Box<T>`]: ../../std/boxed/struct.Box.html
//!
//! The following example uses [`Option`] to create an optional box of
//! [`i32`]. Notice that in order to use the inner [`i32`] value, the
//! `check_optional` function first needs to use pattern matching to
@ -83,6 +85,10 @@
//! * [`ptr::NonNull<U>`]
//! * `#[repr(transparent)]` struct around one of the types in this list.
//!
//! [`Box<U>`]: ../../std/boxed/struct.Box.html
//! [`num::NonZero*`]: crate::num
//! [`ptr::NonNull<U>`]: crate::ptr::NonNull
//!
//! This is called the "null pointer optimization" or NPO.
//!
//! It is further guaranteed that, for the cases above, one can
@ -90,6 +96,339 @@
//! 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_none`]: Option::is_none
//! [`is_some`]: Option::is_some
//!
//! ## 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>>`
//! * [`as_pin_mut`] converts from [`Pin`]`<&mut Option<T>>` to
//! `Option<`[`Pin`]`<&mut T>>`
//!
//! [`as_deref`]: Option::as_deref
//! [`as_deref_mut`]: Option::as_deref_mut
//! [`as_mut`]: Option::as_mut
//! [`as_pin_mut`]: Option::as_pin_mut
//! [`as_pin_ref`]: Option::as_pin_ref
//! [`as_ref`]: Option::as_ref
//!
//! ## Extracting the contained value
//!
//! These methods extract the contained value in an [`Option<T>`] 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`] returns the result of evaluating the provided
//! function
//!
//! [`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
//!
//! These methods transform [`Option`] to [`Result`]:
//!
//! * [`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`] using the provided function
//! * [`transpose`] transposes an [`Option`] of a [`Result`] into a
//! [`Result`] of an [`Option`]
//!
//! [`Err(err)`]: Err
//! [`Ok(v)`]: Ok
//! [`Some(v)`]: Some
//! [`ok_or`]: Option::ok_or
//! [`ok_or_else`]: Option::ok_or_else
//! [`transpose`]: Option::transpose
//!
//! These methods transform the [`Some`] variant:
//!
//! * [`filter`] calls the provided predicate function on the contained
//! value `t` if the [`Option`] is [`Some(t)`], and returns [`Some(t)`]
//! if the function returns `true`; otherwise, returns [`None`]
//! * [`flatten`] removes one level of nesting from an
//! [`Option<Option<T>>`]
//! * [`map`] transforms [`Option<T>`] to [`Option<U>`] by applying the
//! provided function to the contained value of [`Some`] and leaving
//! [`None`] values unchanged
//!
//! [`Some(t)`]: Some
//! [`filter`]: Option::filter
//! [`flatten`]: Option::flatten
//! [`map`]: Option::map
//!
//! These methods transform [`Option<T>`] to a value of a possibly
//! different type `U`:
//!
//! * [`map_or`] applies the provided function to the contained value of
//! [`Some`], or returns the provided default value if the [`Option`] is
//! [`None`]
//! * [`map_or_else`] applies the provided function to the contained value
//! of [`Some`], or returns the result of evaluating the provided
//! fallback function if the [`Option`] is [`None`]
//!
//! [`map_or`]: Option::map_or
//! [`map_or_else`]: Option::map_or_else
//!
//! These methods combine the [`Some`] variants of two [`Option`] values:
//!
//! * [`zip`] returns [`Some((s, o))`] if `self` is [`Some(s)`] and the
//! provided [`Option`] value is [`Some(o)`]; otherwise, returns [`None`]
//! * [`zip_with`] calls the provided function `f` and returns
//! [`Some(f(s, o))`] if `self` is [`Some(s)`] and the provided
//! [`Option`] value is [`Some(o)`]; otherwise, returns [`None`]
//!
//! [`Some(f(s, o))`]: Some
//! [`Some(o)`]: Some
//! [`Some(s)`]: Some
//! [`Some((s, o))`]: Some
//! [`zip`]: Option::zip
//! [`zip_with`]: Option::zip_with
//!
//! ## 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>`].
//!
//! | 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)` |
//! | [`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` |
//!
//! [`and`]: Option::and
//! [`or`]: Option::or
//! [`xor`]: Option::xor
//!
//! 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 [`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)` |
//! | [`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_then`]: Option::and_then
//! [`or_else`]: Option::or_else
//!
//! This is an example of using methods like [`and_then`] and [`or`] in a
//! pipeline of method calls. Early stages of the pipeline pass failure
//! values ([`None`]) through unchanged, and continue processing on
//! success values ([`Some`]). Toward the end, [`or`] substitutes an error
//! message if it receives [`None`].
//!
//! ```
//! # use std::collections::BTreeMap;
//! let mut bt = BTreeMap::new();
//! bt.insert(20u8, "foo");
//! bt.insert(42u8, "bar");
//! let res = vec![0u8, 1, 11, 200, 22]
//! .into_iter()
//! .map(|x| {
//! // `checked_sub()` returns `None` on error
//! x.checked_sub(1)
//! // same with `checked_mul()`
//! .and_then(|x| x.checked_mul(2))
//! // `BTreeMap::get` returns `None` on error
//! .and_then(|x| bt.get(&x))
//! // Substitute an error message if we have `None` so far
//! .or(Some(&"error!"))
//! .copied()
//! // Won't panic because we unconditionally used `Some` above
//! .unwrap()
//! })
//! .collect::<Vec<_>>();
//! assert_eq!(res, ["error!", "error!", "foo", "error!", "bar"]);
//! ```
//!
//! ## Iterating over `Option`
//!
//! 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`].
//!
//! [`Some(v)`]: Some
//! [`empty()`]: crate::iter::empty
//! [`once(v)`]: crate::iter::once
//!
//! Iterators over [`Option<T>`] 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
//!
//! [`into_iter`]: Option::into_iter
//! [`iter`]: Option::iter
//! [`iter_mut`]: Option::iter_mut
//!
//! An iterator over [`Option`] can be useful when chaining iterators, for
//! example, to conditionally insert items. (It's not always necessary to
//! explicitly call an iterator constructor: many [`Iterator`] methods that
//! accept other iterators will also accept iterable types that implement
//! [`IntoIterator`], which includes [`Option`].)
//!
//! ```
//! let yep = Some(42);
//! let nope = None;
//! // chain() already calls into_iter(), so we don't have to do so
//! let nums: Vec<i32> = (0..4).chain(yep).chain(4..8).collect();
//! assert_eq!(nums, [0, 1, 2, 3, 42, 4, 5, 6, 7]);
//! let nums: Vec<i32> = (0..4).chain(nope).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.
//!
//! ```
//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
//! // Explicit returns to illustrate return types matching
//! match do_insert {
//! true => return (0..4).chain(Some(42)).chain(4..8),
//! false => return (0..4).chain(None).chain(4..8),
//! }
//! }
//! println!("{:?}", make_iter(true).collect::<Vec<_>>());
//! println!("{:?}", make_iter(false).collect::<Vec<_>>());
//! ```
//!
//! If we try to do the same thing, but using [`once()`] and [`empty()`],
//! we can't return `impl Iterator` anymore because the concrete types of
//! the return values differ.
//!
//! [`empty()`]: crate::iter::empty
//! [`once()`]: crate::iter::once
//!
//! ```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(do_insert: bool) -> impl Iterator<Item = i32> {
//! // Explicit returns to illustrate return types not matching
//! match x {
//! true => return (0..4).chain(once(42)).chain(4..8),
//! false => return (0..4).chain(empty()).chain(4..8),
//! }
//! }
//! ```
//!
//! ## Collecting into `Option`
//!
//! [`Option`] implements the [`FromIterator`][impl-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`].
//!
//! [impl-FromIterator]: Option#impl-FromIterator%3COption%3CA%3E%3E
//!
//! ```
//! let v = vec![Some(2), Some(4), None, Some(8)];
//! let res: Option<Vec<_>> = v.into_iter().collect();
//! assert_eq!(res, None);
//! let v = vec![Some(2), Some(4), Some(8)];
//! let res: Option<Vec<_>> = v.into_iter().collect();
//! assert_eq!(res, Some(vec![2, 4, 8]));
//! ```
//!
//! [`Option`] also implements the [`Product`][impl-Product] and
//! [`Sum`][impl-Sum] traits, allowing an iterator over [`Option`] values
//! to provide the [`product`][Iterator::product] and
//! [`sum`][Iterator::sum] methods.
//!
//! [impl-Product]: Option#impl-Product%3COption%3CU%3E%3E
//! [impl-Sum]: Option#impl-Sum%3COption%3CU%3E%3E
//!
//! ```
//! let v = vec![None, Some(1), Some(2), Some(3)];
//! let res: Option<i32> = v.into_iter().sum();
//! assert_eq!(res, None);
//! let v = vec![Some(1), Some(2), Some(21)];
//! let res: Option<i32> = v.into_iter().product();
//! assert_eq!(res, Some(42));
//! ```
//!
//! ## Modifying an [`Option`] in-place
//!
//! These methods return a mutable reference to the contained value of an
//! [`Option<T>`]:
//!
//! * [`insert`] inserts a value, dropping any old contents
//! * [`get_or_insert`] gets the current value, inserting a provided
//! default value if it is [`None`]
//! * [`get_or_insert_default`] gets the current value, inserting the
//! default value of type `T` (which must implement [`Default`]) if it is
//! [`None`]
//! * [`get_or_insert_with`] gets the current value, inserting a default
//! computed by the provided function if it is [`None`]
//!
//! [`get_or_insert`]: Option::get_or_insert
//! [`get_or_insert_default`]: Option::get_or_insert_default
//! [`get_or_insert_with`]: Option::get_or_insert_with
//! [`insert`]: Option::insert
//!
//! These methods transfer ownership of the contained value of an
//! [`Option`]:
//!
//! * [`take`] takes ownership of the contained value of an [`Option`], if
//! any, replacing the [`Option`] with [`None`]
//! * [`replace`] takes ownership of the contained value of an [`Option`],
//! if any, replacing the [`Option`] with a [`Some`] containing the
//! provided value
//!
//! [`replace`]: Option::replace
//! [`take`]: Option::take
//!
//! # Examples
//!
//! Basic pattern matching on [`Option`]:
@ -141,11 +480,6 @@
//! None => println!("there are no animals :("),
//! }
//! ```
//!
//! [`Box<T>`]: ../../std/boxed/struct.Box.html
//! [`Box<U>`]: ../../std/boxed/struct.Box.html
//! [`num::NonZero*`]: crate::num
//! [`ptr::NonNull<U>`]: crate::ptr::NonNull
#![stable(feature = "rust1", since = "1.0.0")]

View File

@ -224,6 +224,250 @@
//! [`Ok(T)`]: Ok
//! [`Err(E)`]: Err
//! [`io::Error`]: ../../std/io/struct.Error.html
//!
//! # Method overview
//!
//! In addition to working with pattern matching, [`Result`] provides a
//! wide variety of different methods.
//!
//! ## Querying the variant
//!
//! The [`is_ok`] and [`is_err`] methods return [`true`] if the [`Result`]
//! is [`Ok`] or [`Err`], respectively.
//!
//! [`is_err`]: Result::is_err
//! [`is_ok`]: Result::is_ok
//!
//! ## Adapters for working with references
//!
//! * [`as_ref`] converts from `&Result<T, E>` to `Result<&T, &E>`
//! * [`as_mut`] converts from `&mut Result<T, E>` to `Result<&mut T, &mut E>`
//! * [`as_deref`] converts from `&Result<T, E>` to `Result<&T::Target, &E>`
//! * [`as_deref_mut`] converts from `&mut Result<T, E>` to
//! `Result<&mut T::Target, &mut E>`
//!
//! [`as_deref`]: Result::as_deref
//! [`as_deref_mut`]: Result::as_deref_mut
//! [`as_mut`]: Result::as_mut
//! [`as_ref`]: Result::as_ref
//!
//! ## Extracting contained values
//!
//! These methods extract the contained value in a [`Result<T, E>`] when it
//! is the [`Ok`] variant. If the [`Result`] is [`Err`]:
//!
//! * [`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`] returns the result of evaluating the provided
//! function
//!
//! The panicking methods [`expect`] and [`unwrap`] require `E` to
//! implement the [`Debug`] trait.
//!
//! [`Debug`]: crate::fmt::Debug
//! [`expect`]: Result::expect
//! [`unwrap`]: Result::unwrap
//! [`unwrap_or`]: Result::unwrap_or
//! [`unwrap_or_default`]: Result::unwrap_or_default
//! [`unwrap_or_else`]: Result::unwrap_or_else
//!
//! These methods extract the contained value in a [`Result<T, E>`] when it
//! is the [`Err`] variant. They require `T` to implement the [`Debug`]
//! trait. If the [`Result`] is [`Ok`]:
//!
//! * [`expect_err`] panics with a provided custom message
//! * [`unwrap_err`] panics with a generic message
//!
//! [`Debug`]: crate::fmt::Debug
//! [`expect_err`]: Result::expect_err
//! [`unwrap_err`]: Result::unwrap_err
//!
//! ## Transforming contained values
//!
//! These methods transform [`Result`] to [`Option`]:
//!
//! * [`err`][Result::err] transforms [`Result<T, E>`] into [`Option<E>`],
//! mapping [`Err(e)`] to [`Some(e)`] and [`Ok(v)`] to [`None`]
//! * [`ok`][Result::ok] transforms [`Result<T, E>`] into [`Option<T>`],
//! mapping [`Ok(v)`] to [`Some(v)`] and [`Err(e)`] to [`None`]
//! * [`transpose`] transposes a [`Result`] of an [`Option`] into an
//! [`Option`] of a [`Result`]
//!
// Do NOT add link reference definitions for `err` or `ok`, because they
// will generate numerous incorrect URLs for `Err` and `Ok` elsewhere, due
// to case folding.
//!
//! [`Err(e)`]: Err
//! [`Ok(v)`]: Ok
//! [`Some(e)`]: Option::Some
//! [`Some(v)`]: Option::Some
//! [`transpose`]: Result::transpose
//!
//! This method transforms the contained value of the [`Ok`] variant:
//!
//! * [`map`] transforms [`Result<T, E>`] into [`Result<U, E>`] by applying
//! the provided function to the contained value of [`Ok`] and leaving
//! [`Err`] values unchanged
//!
//! [`map`]: Result::map
//!
//! This method transforms the contained value of the [`Err`] variant:
//!
//! * [`map_err`] transforms [`Result<T, E>`] into [`Result<T, F>`] by
//! applying the provided function to the contained value of [`Err`] and
//! leaving [`Ok`] values unchanged
//!
//! [`map_err`]: Result::map_err
//!
//! These methods transform a [`Result<T, E>`] into a value of a possibly
//! different type `U`:
//!
//! * [`map_or`] applies the provided function to the contained value of
//! [`Ok`], or returns the provided default value if the [`Result`] is
//! [`Err`]
//! * [`map_or_else`] applies the provided function to the contained value
//! of [`Ok`], or applies the provided fallback function to the contained
//! value of [`Err`]
//!
//! [`map_or`]: Result::map_or
//! [`map_or_else`]: Result::map_or_else
//!
//! ## 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 a [`Result`] as output. The [`and`] method can produce a
//! [`Result<U, E>`] value having a different inner type `U` than
//! [`Result<T, E>`]. The [`or`] method can produce a [`Result<T, F>`]
//! value having a different error type `F` 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)` |
//!
//! [`and`]: Result::and
//! [`or`]: Result::or
//!
//! 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. The
//! [`and_then`] method can produce a [`Result<U, E>`] value having a
//! different inner type `U` than [`Result<T, E>`]. The [`or_else`] method
//! can produce a [`Result<T, F>`] value having a different error type `F`
//! than [`Result<T, E>`].
//!
//! | 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_then`]: Result::and_then
//! [`or_else`]: Result::or_else
//!
//! ## Iterating over `Result`
//!
//! A [`Result`] 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 [`Result`] is [`Ok`]), or produce no values
//! (when the [`Result`] is [`Err`]). For example, [`into_iter`] acts like
//! [`once(v)`] if the [`Result`] is [`Ok(v)`], and like [`empty()`] if the
//! [`Result`] is [`Err`].
//!
//! [`Ok(v)`]: Ok
//! [`empty()`]: crate::iter::empty
//! [`once(v)`]: crate::iter::once
//!
//! Iterators over [`Result<T, E>`] come in three types:
//!
//! * [`into_iter`] consumes the [`Result`] 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
//!
//! See [Iterating over `Option`] for examples of how this can be useful.
//!
//! [Iterating over `Option`]: crate::option#iterating-over-option
//! [`into_iter`]: Result::into_iter
//! [`iter`]: Result::iter
//! [`iter_mut`]: Result::iter_mut
//!
//! You might want to use an iterator chain to do multiple instances of an
//! operation that can fail, but would like to ignore failures while
//! continuing to process the successful results. In this example, we take
//! advantage of the iterable nature of [`Result`] to select only the
//! [`Ok`] values using [`flatten`][Iterator::flatten].
//!
//! ```
//! # use std::str::FromStr;
//! let mut results = vec![];
//! let mut errs = vec![];
//! let nums: Vec<_> = vec!["17", "not a number", "99", "-27", "768"]
//! .into_iter()
//! .map(u8::from_str)
//! // Save clones of the raw `Result` values to inspect
//! .inspect(|x| results.push(x.clone()))
//! // Challenge: explain how this captures only the `Err` values
//! .inspect(|x| errs.extend(x.clone().err()))
//! .flatten()
//! .collect();
//! assert_eq!(errs.len(), 3);
//! assert_eq!(nums, [17, 99]);
//! println!("results {:?}", results);
//! println!("errs {:?}", errs);
//! println!("nums {:?}", nums);
//! ```
//!
//! ## Collecting into `Result`
//!
//! [`Result`] implements the [`FromIterator`][impl-FromIterator] trait,
//! which allows an iterator over [`Result`] values to be collected into a
//! [`Result`] of a collection of each contained value of the original
//! [`Result`] values, or [`Err`] if any of the elements was [`Err`].
//!
//! [impl-FromIterator]: Result#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E
//!
//! ```
//! let v = vec![Ok(2), Ok(4), Err("err!"), Ok(8)];
//! let res: Result<Vec<_>, &str> = v.into_iter().collect();
//! assert_eq!(res, Err("err!"));
//! let v = vec![Ok(2), Ok(4), Ok(8)];
//! let res: Result<Vec<_>, &str> = v.into_iter().collect();
//! assert_eq!(res, Ok(vec![2, 4, 8]));
//! ```
//!
//! [`Result`] also implements the [`Product`][impl-Product] and
//! [`Sum`][impl-Sum] traits, allowing an iterator over [`Result`] values
//! to provide the [`product`][Iterator::product] and
//! [`sum`][Iterator::sum] methods.
//!
//! [impl-Product]: Result#impl-Product%3CResult%3CU%2C%20E%3E%3E
//! [impl-Sum]: Result#impl-Sum%3CResult%3CU%2C%20E%3E%3E
//!
//! ```
//! let v = vec![Err("error!"), Ok(1), Ok(2), Ok(3), Err("foo")];
//! let res: Result<i32, &str> = v.into_iter().sum();
//! assert_eq!(res, Err("error!"));
//! let v: Vec<Result<i32, &str>> = vec![Ok(1), Ok(2), Ok(21)];
//! let res: Result<i32, &str> = v.into_iter().product();
//! assert_eq!(res, Ok(42));
//! ```
#![stable(feature = "rust1", since = "1.0.0")]