2023-05-17 12:08:17 +00:00
|
|
|
use std::error;
|
|
|
|
use std::fmt;
|
|
|
|
use std::fmt::Write;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
2023-05-17 13:47:40 +00:00
|
|
|
/// Unexpected is a String which implements the Error trait. It is intended to be used in
|
|
|
|
/// situations where the caller is being given an error they can't really handle, except to pass it
|
|
|
|
/// along or log it.
|
|
|
|
///
|
|
|
|
/// The error is intended to also implement Send + Sync + Clone, such that it is easy to use in
|
|
|
|
/// async situations.
|
2023-05-17 12:08:17 +00:00
|
|
|
pub struct Unexpected(String);
|
|
|
|
|
|
|
|
impl fmt::Display for Unexpected {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "Unexpected error occurred: {}", self.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl error::Error for Unexpected {}
|
|
|
|
|
|
|
|
impl From<&str> for Unexpected {
|
|
|
|
fn from(s: &str) -> Self {
|
|
|
|
Unexpected(s.to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait ToUnexpected {
|
|
|
|
fn to_unexpected(&self) -> Unexpected;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<E: error::Error> ToUnexpected for E {
|
|
|
|
fn to_unexpected(&self) -> Unexpected {
|
|
|
|
let mut w = String::new();
|
|
|
|
write!(w, "{}", self.to_string()).expect("underlying error formatted correctly");
|
|
|
|
|
|
|
|
if let Some(src) = self.source() {
|
|
|
|
write!(w, " [{src}]").expect("underyling source formatted correctly");
|
|
|
|
}
|
|
|
|
|
|
|
|
Unexpected(w.to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait MapUnexpected<T> {
|
|
|
|
fn map_unexpected(self) -> Result<T, Unexpected>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T, E: ToUnexpected> MapUnexpected<T> for Result<T, E> {
|
|
|
|
fn map_unexpected(self) -> Result<T, Unexpected> {
|
|
|
|
match self {
|
|
|
|
Ok(t) => Ok(t),
|
|
|
|
Err(err) => Err(err.to_unexpected()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|