51 lines
1.2 KiB
Rust
51 lines
1.2 KiB
Rust
|
use std::error;
|
||
|
use std::fmt;
|
||
|
use std::fmt::Write;
|
||
|
|
||
|
#[derive(Debug, Clone)]
|
||
|
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()),
|
||
|
}
|
||
|
}
|
||
|
}
|