use std::fmt;
use super::chain;
#[derive(Debug)]
struct Layer {
text: &'static str,
cause: Option<Box<Self>>,
}
impl fmt::Display for Layer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.text)
}
}
impl std::error::Error for Layer {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.cause
.as_deref()
.map(|c| c as &(dyn std::error::Error + 'static))
}
}
#[test]
fn causes_hidden_by_display_are_appended_in_order() {
let e = Layer {
text: "connection error",
cause: Some(Box::new(Layer {
text: "tcp connect",
cause: Some(Box::new(Layer {
text: "Connection refused (os error 111)",
cause: None,
})),
})),
};
assert_eq!(
chain(&e),
"connection error: tcp connect: Connection refused (os error 111)"
);
}
#[test]
fn a_cause_the_display_already_shows_is_not_repeated() {
let e = Layer {
text: "HTTP error: timed out",
cause: Some(Box::new(Layer {
text: "timed out",
cause: None,
})),
};
assert_eq!(chain(&e), "HTTP error: timed out");
}
#[test]
fn an_error_with_no_source_is_just_its_text() {
let e = Layer {
text: "alone",
cause: None,
};
assert_eq!(chain(&e), "alone");
}