diff options
| -rw-r--r-- | src/exun.rs | 4 | ||||
| -rw-r--r-- | src/lib.rs | 3 | ||||
| -rw-r--r-- | src/result.rs | 140 |
3 files changed, 143 insertions, 4 deletions
diff --git a/src/exun.rs b/src/exun.rs index 53e877b..f6bf24e 100644 --- a/src/exun.rs +++ b/src/exun.rs @@ -235,7 +235,7 @@ impl<E, U> Exun<E, U> { /// /// ```should_panic /// let path = std::env::var("IMPORTANT_PATH") - /// .expect("env variable `IMPORTANT_PATH` should be set by script.sh") + /// .expect("env variable `IMPORTANT_PATH` should be set by test.sh"); /// ``` /// /// **Hint:** If you're having trouble remembering how to phrase expect @@ -311,7 +311,7 @@ impl<E, U> Exun<E, U> { /// use exun::*; /// /// let x: Exun<u32, &str> = Expected(2); - /// x.unwrap_unexpected(); // panics wirh `2` + /// x.unwrap_unexpected(); // panics with `2` /// ``` /// /// ``` @@ -3,6 +3,7 @@ #![warn(clippy::pedantic)] #![warn(clippy::cargo)] #![allow(clippy::module_name_repetitions)] +#![allow(clippy::missing_errors_doc)] //! There are many errors we don't expect to occur. But what if we're wrong? We //! don't want our programs to panic because of that. We also don't want to spend //! so much time handling unexpected errors. That's what this crate is for. You @@ -150,7 +151,7 @@ pub use crate::exun::Exun; #[cfg(feature = "std")] pub use result::ResultErrorExt; #[cfg(feature = "alloc")] -pub use result::ResultMsgExt; +pub use result::{ResultExunExt, ResultMsgExt}; #[cfg(feature = "alloc")] pub use unexpected::{RawUnexpected, UnexpectedError}; pub use Exun::{Expected, Unexpected}; diff --git a/src/result.rs b/src/result.rs index 6b3ad32..b67370c 100644 --- a/src/result.rs +++ b/src/result.rs @@ -133,24 +133,162 @@ impl<T, E: Errorable + 'static> ResultMsgExt<T> for Result<T, E> { } } -trait ResultExunExt<T, E, U>: Sealed { +pub trait ResultExunExt<T, E, U>: Sealed { + /// Converts [`Result<T, Exun<E, U>>`] to [`Option<E>`]. + /// + /// Converts self into an [`Option<E>`], consuming `self`, and discarding + /// success value and the unexpected error, if any. + /// + /// # Examples + /// + /// ``` + /// use exun::{Expected, Exun, ResultExunExt}; + /// + /// let x: Result<u32, Exun<&str, &str>> = Ok(2); + /// assert_eq!(x.expected_err(), None); + /// + /// let x: Result<u32, Exun<&str, &str>> = Err(Expected("expected")); + /// assert_eq!(x.expected_err(), Some("expected")); + /// ``` fn expected_err(self) -> Option<E>; + /// Converts [`Result<T, Exun<E, U>>`] to [`Option<U>`]. + /// + /// Converts self into an [`Option<U>`], consuming `self`, and discarding + /// success value and the expected error, if any. + /// + /// # Examples + /// + /// ``` + /// use exun::{Exun, ResultExunExt, Unexpected}; + /// + /// let x: Result<u32, Exun<&str, &str>> = Ok(2); + /// assert_eq!(x.unexpected_err(), None); + /// + /// let x: Result<u32, Exun<&str, &str>> = Err(Unexpected("unexpected")); + /// assert_eq!(x.unexpected_err(), Some("unexpected")); + /// ``` fn unexpected_err(self) -> Option<U>; + /// Maps a [`Result<T, Exun<E, U>>`] to `Result<T, Exun<F, U>>` by applying + /// a function to a contained `Err(Expected)` value, leaving the `Ok` and + /// `Err(Unexpected)` values untouched. + /// + /// This function can be used to pass through a successful result while + /// handling an expected error. + /// + /// # Examples + /// + /// ``` + /// use exun::{Exun, ResultExunExt, Expected}; + /// + /// fn stringify(x: u32) -> String { format!("error code: {x}") } + /// + /// let x: Result<u32, Exun<u32, &str>> = Ok(2); + /// assert_eq!(x.map_expected_err(stringify), Ok(2)); + /// + /// let x: Result<u32, Exun<u32, &str>> = Err(Expected(13)); + /// assert_eq!(x.map_expected_err(stringify), Err(Expected("error code: 13".to_string()))); + /// ``` fn map_expected_err<F>(self, op: impl FnOnce(E) -> F) -> Result<T, Exun<F, U>>; + /// Maps a [`Result<T, Exun<E, U>>`] to `Result<T, Exun<E, F>>` by applying + /// a function to a contained `Err(Unexpected)` value, leaving the `Ok` and + /// `Err(Expected)` values untouched. + /// + /// This function can be used to pass through a successful result while + /// handling an unexpected error. + /// + /// # Examples + /// + /// ``` + /// use exun::{Exun, ResultExunExt, Unexpected}; + /// + /// fn stringify(x: &str) -> String { format!("error: {x}") } + /// + /// let x: Result<u32, Exun<u32, &str>> = Ok(2); + /// assert_eq!(x.map_unexpected_err(stringify), Ok(2)); + /// + /// let x: Result<u32, Exun<u32, &str>> = Err(Unexpected("hi")); + /// assert_eq!(x.map_unexpected_err(stringify), Err(Unexpected("error: hi".to_string()))); + /// ``` fn map_unexpected_err<F>(self, op: impl FnOnce(U) -> F) -> Result<T, Exun<E, F>>; + /// Converts [`Result<T, Exun<E, U>>`] to `Result<T, E>`, consuming the + /// self value. + /// + /// Because this function may panic, its use is generally discouraged. + /// Instead, prefer to use pattern matching and handle the [`Unexpected`] + /// case explicitly. + /// + /// # Panics + /// + /// Panics if the value is an [`Unexpected`], with a panic message provided + /// by the [`Unexpected`]'s value. + /// + /// # Examples + /// + /// ``` + /// use exun::{Exun, ResultExunExt}; + /// + /// let x: Result<u32, Exun<&str, &str>> = Ok(2); + /// assert_eq!(x.unwrap_result(), Ok(2)); + /// ``` + /// + /// [`Unexpected`]: crate::Unexpected fn unwrap_result(self) -> Result<T, E> where U: Debug; + /// Returns the contained [`Expected`] value, consuming the `self` value. + /// + /// Because this function may panic, its use is generally discouraged. + /// Instead, prefer to use pattern matching and handle the [`Unexpected`] + /// case explicitly. + /// + /// # Panics + /// + /// Panics if the value is an [`Unexpected`], with a panic message provided + /// by the [`Unexpected`]'s value. + /// + /// # Examples + /// + /// ``` + /// use exun::{Expected, Exun, ResultExunExt}; + /// + /// let x: Result<u32, Exun<&str, &str>> = Err(Expected("failure")); + /// assert_eq!(x.unwrap_expected_err(), "failure"); + /// ``` + /// + /// [`Expected`]: crate::Expected + /// [`Unexpected`]: crate::Unexpected fn unwrap_expected_err(self) -> E where T: Debug, U: Debug; + /// Returns the contained [`Unexpected`] value, consuming the `self` value. + /// + /// Because this function may panic, its use is generally discouraged. + /// Instead, prefer to use pattern matching and handle the [`Expected`] + /// case explicitly. + /// + /// # Panics + /// + /// Panics if the value is an [`Expected`], with a panic message provided + /// by the [`Expected`]'s value. + /// + /// # Examples + /// + /// ``` + /// use exun::{Exun, ResultExunExt, Unexpected}; + /// + /// let x: Result<u32, Exun<&str, &str>> = Err(Unexpected("failure")); + /// assert_eq!(x.unwrap_unexpected_err(), "failure"); + /// ``` + /// + /// [`Expected`]: crate::Expected + /// [`Unexpected`]: crate::Unexpected fn unwrap_unexpected_err(self) -> U where T: Debug, |
