summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exun.rs4
-rw-r--r--src/lib.rs3
-rw-r--r--src/result.rs140
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`
/// ```
///
/// ```
diff --git a/src/lib.rs b/src/lib.rs
index 255bb4c..7b1e787 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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,