use std::error;
use std::fmt::{Display, Formatter, Result};
use tracing::debug;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Error {
failures: Vec<String>,
}
impl Error {
#[inline]
pub fn new<S: AsRef<str>>(failure: S) -> Self {
Self::many([failure])
}
pub fn many<S, I>(failures: I) -> Self
where
S: AsRef<str>,
I: IntoIterator<Item = S>,
{
Self {
failures: failures
.into_iter()
.map(|failure| {
let failure = failure.as_ref().to_owned();
debug!("{failure}");
failure
})
.collect(),
}
}
#[inline]
pub fn failures(&self) -> &[String] {
&self.failures
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
let mut failures = self.failures.iter();
if let Some(failure) = failures.next() {
failure.fmt(f)?;
for failure in failures {
f.write_str("; ")?;
failure.fmt(f)?;
}
}
Ok(())
}
}
impl error::Error for Error {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_should_return_message() {
let result = Error::new("Failed");
let message = result.to_string();
assert_eq!(message, "Failed");
}
#[test]
fn many_should_return_joined_message() {
let failures = ["Failure 1", "Failure 2"];
let result = Error::many(failures);
let message = result.to_string();
assert_eq!(message, "Failure 1; Failure 2");
}
#[test]
fn many_should_return_failures() {
let expected = ["Failure 1", "Failure 2"];
let result = Error::many(&expected);
let failures = result.failures();
assert_eq!(failures, &expected[..]);
}
}