use std::error::Error;
use std::fmt::{Display, Formatter};
use super::TemplateEngineException;
#[derive(Debug)]
pub struct AlreadyInitializedException {
message: Option<String>,
cause: Option<Box<dyn Error + Send + Sync>>,
}
impl AlreadyInitializedException {
#[must_use]
pub fn new(message: Option<String>) -> Self {
Self {
message,
cause: None,
}
}
pub fn with_cause<E>(message: Option<String>, cause: E) -> Self
where
E: Error + Send + Sync + 'static,
{
Self {
message,
cause: Some(Box::new(cause)),
}
}
#[must_use]
pub fn get_message(&self) -> Option<&str> {
self.message.as_deref()
}
}
impl Display for AlreadyInitializedException {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.message.as_deref().unwrap_or("null"))
}
}
impl Error for AlreadyInitializedException {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.cause
.as_deref()
.map(|cause| cause as &(dyn Error + 'static))
}
}
impl TemplateEngineException for AlreadyInitializedException {}
#[cfg(test)]
mod tests {
use std::error::Error;
use std::io;
use super::AlreadyInitializedException;
#[test]
fn preserves_message_and_optional_cause() {
let without_cause = AlreadyInitializedException::new(Some("initialized".to_owned()));
assert_eq!(without_cause.get_message(), Some("initialized"));
assert_eq!(without_cause.to_string(), "initialized");
assert!(without_cause.source().is_none());
let null_message = AlreadyInitializedException::new(None);
assert_eq!(null_message.get_message(), None);
assert_eq!(null_message.to_string(), "null");
let with_cause = AlreadyInitializedException::with_cause(
Some("initialized".to_owned()),
io::Error::other("cause"),
);
assert_eq!(
with_cause.source().map(ToString::to_string),
Some("cause".to_owned())
);
}
}