1use std::fmt::{Display, Formatter, Result as FormatResult};
2
3#[derive(Clone, Debug)]
5pub struct ValidateOptionsResult {
6 succeeded: bool,
7 skipped: bool,
8 failed: bool,
9 failures: Vec<String>,
10}
11
12impl ValidateOptionsResult {
13 pub fn succeeded(&self) -> bool {
15 self.succeeded
16 }
17
18 pub fn skipped(&self) -> bool {
20 self.skipped
21 }
22
23 pub fn failed(&self) -> bool {
25 self.failed
26 }
27
28 pub fn failure_message(&self) -> String {
30 if self.failures.is_empty() {
31 String::new()
32 } else {
33 self.failures.join("; ")
34 }
35 }
36
37 pub fn failures(&self) -> &[String] {
39 &self.failures
40 }
41
42 pub fn skip() -> Self {
44 Self {
45 succeeded: false,
46 skipped: true,
47 failed: false,
48 failures: Vec::with_capacity(0),
49 }
50 }
51
52 pub fn success() -> Self {
54 Self {
55 succeeded: true,
56 skipped: false,
57 failed: false,
58 failures: Vec::with_capacity(0),
59 }
60 }
61
62 pub fn fail<S: AsRef<str>>(failure: S) -> Self {
68 Self::fail_many([failure].iter())
69 }
70
71 pub fn fail_many<S, I>(failures: I) -> Self
73 where
74 S: AsRef<str>,
75 I: Iterator<Item = S>,
76 {
77 Self {
78 succeeded: false,
79 skipped: false,
80 failed: true,
81 failures: failures.map(|f| f.as_ref().to_owned()).collect(),
82 }
83 }
84}
85
86impl Display for ValidateOptionsResult {
87 fn fmt(&self, formatter: &mut Formatter<'_>) -> FormatResult {
88 formatter.write_str(&self.failure_message())
89 }
90}
91
92#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
94pub trait ValidateOptions<T> {
95 fn validate(&self, name: Option<&str>, options: &T) -> ValidateOptionsResult;
102}
103
104#[cfg(test)]
105mod tests {
106
107 use super::*;
108
109 #[test]
110 fn success_should_indicate_succeed() {
111 let result = ValidateOptionsResult::success();
113
114 let succeeded = result.succeeded();
116
117 assert!(succeeded);
119 }
120
121 #[test]
122 fn skip_should_indicate_skipped() {
123 let result = ValidateOptionsResult::skip();
125
126 let skipped = result.skipped();
128
129 assert!(skipped);
131 }
132
133 #[test]
134 fn fail_should_return_failed() {
135 let result = ValidateOptionsResult::fail("");
137
138 let failed = result.failed();
140
141 assert!(failed);
143 }
144
145 #[test]
146 fn fail_should_return_message() {
147 let result = ValidateOptionsResult::fail("Failed");
149
150 let message = result.failure_message();
152
153 assert_eq!(&message, "Failed");
155 }
156
157 #[test]
158 fn fail_many_should_return_joined_message() {
159 let failures = ["Failure 1", "Failure 2"];
161 let result = ValidateOptionsResult::fail_many(failures.iter());
162
163 let message = result.failure_message();
165
166 assert_eq!(&message, "Failure 1; Failure 2");
168 }
169
170 #[test]
171 fn fail_many_should_return_failures() {
172 let expected = ["Failure 1", "Failure 2"];
174 let result = ValidateOptionsResult::fail_many(expected.iter());
175
176 let failures = result.failures();
178
179 assert_eq!(failures, &expected[..]);
181 }
182
183 #[test]
184 fn to_string_should_return_message() {
185 let result = ValidateOptionsResult::fail("Failed");
187 let message = result.failure_message();
188
189 let string = result.to_string();
191
192 assert_eq!(string, message);
194 }
195}