Got error source working.

This commit is contained in:
Jeff Baskin 2022-07-23 21:28:34 -04:00
parent ec95a0bbf2
commit 59361c0a87

View File

@ -1,39 +1,112 @@
use std::{error::Error, fmt}; use std::{error::Error, fmt, sync::Arc};
#[derive(Debug)] #[derive(Debug)]
pub struct MTTError { pub enum MTTError {
detail: String, Generic(Generic),
} }
impl MTTError { impl Error for MTTError {
fn new(detail: &str) -> Self { fn source(&self) -> Option<&(dyn Error + 'static)> {
Self { match self {
detail: detail.to_string(), MTTError::Generic(err) => err.source(),
} }
} }
} }
impl fmt::Display for MTTError { impl fmt::Display for MTTError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MTTError::Generic(err) => write!(f, "{}", err),
}
}
}
impl From<Generic> for MTTError {
fn from(err: Generic) -> Self {
MTTError::Generic(err)
}
}
#[derive(Debug)]
pub struct Generic {
detail: String,
source: Option<Arc<MTTError>>,
}
impl Generic {
fn new(detail: &str) -> Self {
Self {
detail: detail.to_string(),
source: None,
}
}
fn add_source(&mut self, source: MTTError) {
self.source = Some(Arc::new(source));
}
}
impl Error for Generic {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match &self.source {
Some(err) => Some(err.as_ref()),
None => None,
}
}
}
impl fmt::Display for Generic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.detail) write!(f, "{}", self.detail)
} }
} }
impl Error for MTTError {}
#[cfg(test)] #[cfg(test)]
mod errors { mod generics {
use super::*; use super::*;
#[test] #[test]
fn new_error() { fn new_error() {
let detail = "new error"; let detail = "new error";
let err = MTTError::new(detail); let err = Generic::new(detail);
assert!( assert!(
err.to_string() == detail, err.to_string() == detail,
"\n\nGot: {}\nWant: {}\n\n", "\n\nGot: {}\nWant: {}\n\n",
err.to_string(), err.to_string(),
detail detail
); );
assert!(
err.source().is_none(),
"Error source should initialoze to None."
);
let error: MTTError = err.into();
assert!(
error.to_string() == detail,
"\n\nGot: {}\nWant: {}\n\n",
error.to_string(),
detail
);
}
#[test]
fn error_with_source() {
let par_detail = "parent error";
let cld_detail = "child error";
let par_err = Generic::new(par_detail);
let mut cld_err = Generic::new(cld_detail);
cld_err.add_source(par_err.into());
assert!(
cld_err.source().unwrap().to_string() == par_detail,
"/n/nGot: {}\nWant: {}\n\n",
cld_err.source().unwrap().to_string(),
par_detail
);
let error: MTTError = cld_err.into();
assert!(
error.source().unwrap().to_string() == par_detail,
"/n/nGot: {}\nWant: {}\n\n",
error.source().unwrap().to_string(),
par_detail
);
} }
} }