diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 444de78a464..75ba70dea1f 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -227,6 +227,103 @@ //! //! # 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` to `Result<&T, &E>` +//! * [`as_mut`] converts from `&mut Result` to `Result<&mut T, &mut E>` +//! * [`as_deref`] converts from `&Result` to `Result<&T::Target, &E>` +//! * [`as_deref_mut`] converts from `&mut Result` 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`] 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. +//! +//! These methods extract the contained value in a [`Result`] 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 +//! [`Default`]: crate::default::Default +//! [`expect`]: Result::expect +//! [`expect_err`]: Result::expect_err +//! [`unwrap`]: Result::unwrap +//! [`unwrap_err`]: Result::unwrap_err +//! [`unwrap_or`]: Result::unwrap_or +//! [`unwrap_or_default`]: Result::unwrap_or_default +//! [`unwrap_or_else`]: Result::unwrap_or_else +//! +//! ## Transforming contained values +//! +//! These transformations are from [`Result`] to [`Option`]: +//! +//! * [`err`][Result::err] transforms [`Result`] into [`Option`], +//! mapping [`Err(e)`] to [`Some(e)`] and [`Ok(v)`] to [`None`] +//! * [`ok`][Result::ok] transforms [`Result`] into [`Option`], +//! mapping [`Ok(v)`] to [`Some(v)`] and [`Err(e)`] to [`None`] +//! * [`transpose`] transposes a [`Result`] of an [`Option`] into an +//! [`Option`] of a [`Result`] +//! +//! These transformations are on [`Ok`] values: +//! +//! * [`map`] transforms [`Result`] into [`Result`] by applying +//! the provided function to the contained value of [`Ok`] and leaving +//! [`Err`] values unchanged +//! * [`map_or`] transforms [`Result`] into a value of `U` by +//! applying the provided function to the contained value of [`Ok`], or +//! returns the provided default value of `U` if the [`Result`] is +//! [`Err`] +//! * [`map_or_else`] transforms [`Result`] into a value of `U` by +//! applying the provided function to the contained value of [`Ok`], or +//! applies the provided fallback function to the contained value of +//! [`Err`] +//! +//! This transformation is on [`Err`] values: +//! +//! * [`map_err`] transforms [`Result`] into [`Result`] by +//! applying the provided function to the contained value of [`Err`] and +//! leaving [`Ok`] values unchanged +//! +//! [`Err(e)`]: Err +//! [`Ok(v)`]: Ok +//! [`Some(e)`]: Option::Some +//! [`Some(v)`]: Option::Some +//! [`map`]: Result::map +//! [`map_err`]: Result::map_err +//! [`map_or`]: Result::map_or +//! [`map_or_else`]: Result::map_or_else +//! [`transpose`]: Result::transpose +//! //! ## Boolean operators //! //! These methods treat the [`Result`] as a boolean value, where [`Ok`] @@ -269,6 +366,90 @@ //! [`and_then`]: Result::and_then //! [`or`]: Result::or //! [`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(err)`]. +//! +//! Iterators over [`Result`] 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. +//! +//! [`Err(err)`]: Err +//! [Iterating over `Option`]: crate::option#iterating-over-option +//! [`Ok(v)`]: Ok +//! [`empty()`]: crate::iter::empty +//! [`into_iter`]: Result::into_iter +//! [`iter`]: Result::iter +//! [`iter_mut`]: Result::iter_mut +//! [`once(v)`]: crate::iter::once +//! +//! 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`]. +//! +//! [`flatten`]: crate::iter::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`] 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`]. +//! +//! [`FromIterator`]: Result#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E +//! +//! ``` +//! let v = vec![Ok(2), Ok(4), Err("err!"), Ok(8)]; +//! let res: Result, &str> = v.into_iter().collect(); +//! assert_eq!(res, Err("err!")); +//! let v = vec![Ok(2), Ok(4), Ok(8)]; +//! let res: Result, &str> = v.into_iter().collect(); +//! assert_eq!(res, Ok(vec![2, 4, 8])); +//! ``` +//! +//! [`Result`] also implements the [`Product`] and [`Sum`] traits, allowing +//! an iterator over [`Result`] values to provide the +//! [`product`][m.product] and [`sum`][m.sum] methods. +//! +//! [`Product`]: Result#impl-Product%3CResult%3CU%2C%20E%3E%3E +//! [`Sum`]: Result#impl-Sum%3CResult%3CU%2C%20E%3E%3E +//! [m.product]: crate::iter::Iterator::product +//! [m.sum]: crate::iter::Iterator::sum #![stable(feature = "rust1", since = "1.0.0")]