options/validation/
error.rs1use std::error;
2use std::fmt::{Display, Formatter, Result};
3use tracing::debug;
4
5#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct Error {
8 failures: Vec<String>,
9}
10
11impl Error {
12 #[inline]
18 pub fn new<S: AsRef<str>>(failure: S) -> Self {
19 Self::many([failure])
20 }
21
22 pub fn many<S, I>(failures: I) -> Self
28 where
29 S: AsRef<str>,
30 I: IntoIterator<Item = S>,
31 {
32 Self {
33 failures: failures
34 .into_iter()
35 .map(|failure| {
36 let failure = failure.as_ref().to_owned();
37 debug!("{failure}");
38 failure
39 })
40 .collect(),
41 }
42 }
43
44 #[inline]
46 pub fn failures(&self) -> &[String] {
47 &self.failures
48 }
49}
50
51impl Display for Error {
52 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
53 let mut failures = self.failures.iter();
54
55 if let Some(failure) = failures.next() {
56 failure.fmt(f)?;
57
58 for failure in failures {
59 f.write_str("; ")?;
60 failure.fmt(f)?;
61 }
62 }
63
64 Ok(())
65 }
66}
67
68impl error::Error for Error {}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn new_should_return_message() {
76 let result = Error::new("Failed");
78
79 let message = result.to_string();
81
82 assert_eq!(message, "Failed");
84 }
85
86 #[test]
87 fn many_should_return_joined_message() {
88 let failures = ["Failure 1", "Failure 2"];
90 let result = Error::many(failures);
91
92 let message = result.to_string();
94
95 assert_eq!(message, "Failure 1; Failure 2");
97 }
98
99 #[test]
100 fn many_should_return_failures() {
101 let expected = ["Failure 1", "Failure 2"];
103 let result = Error::many(&expected);
104
105 let failures = result.failures();
107
108 assert_eq!(failures, &expected[..]);
110 }
111}