introduce unexpected::Result

This commit is contained in:
Brian Picciano 2023-07-12 19:01:15 +02:00
parent af1dc183ec
commit 811aef209a

View File

@ -1,5 +1,5 @@
use std::fmt::Write; use std::fmt::Write;
use std::{error, fmt}; use std::{error, fmt, result};
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
/// Error is a String which implements the Error trait. It is intended to be used in /// Error is a String which implements the Error trait. It is intended to be used in
@ -10,6 +10,8 @@ use std::{error, fmt};
/// async situations. /// async situations.
pub struct Error(String); pub struct Error(String);
pub type Result<T> = result::Result<T, Error>;
impl Error { impl Error {
fn from_displays<D1, D2, D3>(prefix: Option<D1>, body: &D2, source: Option<D3>) -> Error fn from_displays<D1, D2, D3>(prefix: Option<D1>, body: &D2, source: Option<D3>) -> Error
where where
@ -55,24 +57,24 @@ impl error::Error for Error {}
pub trait Mappable<T> { pub trait Mappable<T> {
/// or_unexpected returns an Err(Error) wrapping self's Err, or the Ok value of self. /// or_unexpected returns an Err(Error) wrapping self's Err, or the Ok value of self.
fn or_unexpected(self) -> Result<T, Error>; fn or_unexpected(self) -> Result<T>;
/// or_unexpected_while is like or_unexpected, but will prefix the error message. The prefix /// or_unexpected_while is like or_unexpected, but will prefix the error message. The prefix
/// should be worded as if it started with the word "while", e.g.: `opening file {path}`. /// should be worded as if it started with the word "while", e.g.: `opening file {path}`.
fn or_unexpected_while<D: fmt::Display>(self, prefix: D) -> Result<T, Error>; fn or_unexpected_while<D: fmt::Display>(self, prefix: D) -> Result<T>;
/// map_unexpected_while is like or_unexpected_while, but uses a closure to produce the error /// map_unexpected_while is like or_unexpected_while, but uses a closure to produce the error
/// prefix. /// prefix.
fn map_unexpected_while<F, D>(self, f: F) -> Result<T, Error> fn map_unexpected_while<F, D>(self, f: F) -> Result<T>
where where
F: FnOnce() -> D, F: FnOnce() -> D,
D: fmt::Display; D: fmt::Display;
} }
fn map_unexpected_maybe_while<T, E, F, D>( fn map_unexpected_maybe_while<T, E, F, D>(
res: Result<T, E>, res: result::Result<T, E>,
prefix_fn: Option<F>, prefix_fn: Option<F>,
) -> Result<T, Error> ) -> Result<T>
where where
E: error::Error, E: error::Error,
F: FnOnce() -> D, F: FnOnce() -> D,
@ -84,17 +86,17 @@ where
} }
} }
impl<T, E: error::Error> Mappable<T> for Result<T, E> { impl<T, E: error::Error> Mappable<T> for result::Result<T, E> {
fn or_unexpected(self) -> Result<T, Error> { fn or_unexpected(self) -> Result<T> {
let no_fn = None::<Box<dyn FnOnce() -> Box<dyn fmt::Display>>>; // lol, good job rust let no_fn = None::<Box<dyn FnOnce() -> Box<dyn fmt::Display>>>; // lol, good job rust
map_unexpected_maybe_while(self, no_fn) map_unexpected_maybe_while(self, no_fn)
} }
fn or_unexpected_while<D: fmt::Display>(self, prefix: D) -> Result<T, Error> { fn or_unexpected_while<D: fmt::Display>(self, prefix: D) -> Result<T> {
map_unexpected_maybe_while(self, Some(|| prefix)) map_unexpected_maybe_while(self, Some(|| prefix))
} }
fn map_unexpected_while<F, D>(self, f: F) -> Result<T, Error> fn map_unexpected_while<F, D>(self, f: F) -> Result<T>
where where
F: FnOnce() -> D, F: FnOnce() -> D,
D: fmt::Display, D: fmt::Display,
@ -106,16 +108,16 @@ impl<T, E: error::Error> Mappable<T> for Result<T, E> {
static OPTION_NONE_ERROR: &str = "expected Some but got None"; static OPTION_NONE_ERROR: &str = "expected Some but got None";
impl<T> Mappable<T> for Option<T> { impl<T> Mappable<T> for Option<T> {
fn or_unexpected(self) -> Result<T, Error> { fn or_unexpected(self) -> Result<T> {
self.ok_or(Error::from(OPTION_NONE_ERROR)).or_unexpected() self.ok_or(Error::from(OPTION_NONE_ERROR)).or_unexpected()
} }
fn or_unexpected_while<D: fmt::Display>(self, prefix: D) -> Result<T, Error> { fn or_unexpected_while<D: fmt::Display>(self, prefix: D) -> Result<T> {
self.ok_or(Error::from(OPTION_NONE_ERROR)) self.ok_or(Error::from(OPTION_NONE_ERROR))
.or_unexpected_while(prefix) .or_unexpected_while(prefix)
} }
fn map_unexpected_while<F, D>(self, f: F) -> Result<T, Error> fn map_unexpected_while<F, D>(self, f: F) -> Result<T>
where where
F: FnOnce() -> D, F: FnOnce() -> D,
D: fmt::Display, D: fmt::Display,