1use crate::{
16 description::Description,
17 matcher::{Matcher, MatcherBase, MatcherResult},
18};
19use std::fmt::Debug;
20
21pub fn ok<InnerMatcherT>(inner: InnerMatcherT) -> OkMatcher<InnerMatcherT> {
42 OkMatcher { inner }
43}
44
45#[derive(MatcherBase)]
46pub struct OkMatcher<InnerMatcherT> {
47 inner: InnerMatcherT,
48}
49
50impl<T: Debug + Copy, E: Debug + Copy, InnerMatcherT: Matcher<T>> Matcher<std::result::Result<T, E>>
51 for OkMatcher<InnerMatcherT>
52{
53 fn matches(&self, actual: std::result::Result<T, E>) -> MatcherResult {
54 actual.map(|v| self.inner.matches(v)).unwrap_or(MatcherResult::NoMatch)
55 }
56
57 fn explain_match(&self, actual: std::result::Result<T, E>) -> Description {
58 match actual {
59 Ok(o) => {
60 Description::new().text("which is a success").nested(self.inner.explain_match(o))
61 }
62 Err(_) => "which is an error".into(),
63 }
64 }
65
66 fn describe(&self, matcher_result: MatcherResult) -> Description {
67 match matcher_result {
68 MatcherResult::Match => format!(
69 "is a success containing a value, which {}",
70 self.inner.describe(MatcherResult::Match)
71 )
72 .into(),
73 MatcherResult::NoMatch => format!(
74 "is an error or a success containing a value, which {}",
75 self.inner.describe(MatcherResult::NoMatch)
76 )
77 .into(),
78 }
79 }
80}
81
82impl<'a, T: Debug, E: Debug, InnerMatcherT: Matcher<&'a T>> Matcher<&'a std::result::Result<T, E>>
83 for OkMatcher<InnerMatcherT>
84{
85 fn matches(&self, actual: &'a std::result::Result<T, E>) -> MatcherResult {
86 actual.as_ref().map(|v| self.inner.matches(v)).unwrap_or(MatcherResult::NoMatch)
87 }
88
89 fn explain_match(&self, actual: &'a std::result::Result<T, E>) -> Description {
90 match actual {
91 Ok(o) => {
92 Description::new().text("which is a success").nested(self.inner.explain_match(o))
93 }
94 Err(_) => "which is an error".into(),
95 }
96 }
97
98 fn describe(&self, matcher_result: MatcherResult) -> Description {
99 match matcher_result {
100 MatcherResult::Match => format!(
101 "is a success containing a value, which {}",
102 self.inner.describe(MatcherResult::Match)
103 )
104 .into(),
105 MatcherResult::NoMatch => format!(
106 "is an error or a success containing a value, which {}",
107 self.inner.describe(MatcherResult::NoMatch)
108 )
109 .into(),
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use crate::matcher::MatcherResult;
117 use crate::prelude::*;
118 use crate::Result;
119 use indoc::indoc;
120
121 #[test]
122 fn ok_matches_result_with_value() -> Result<()> {
123 let matcher = ok(eq(1));
124 let value: std::result::Result<i32, i32> = Ok(1);
125
126 let result = matcher.matches(value);
127
128 verify_that!(result, eq(MatcherResult::Match))
129 }
130
131 #[test]
132 fn ok_does_not_match_result_with_wrong_value() -> Result<()> {
133 let matcher = ok(eq(1));
134 let value: std::result::Result<i32, i32> = Ok(0);
135
136 let result = matcher.matches(value);
137
138 verify_that!(result, eq(MatcherResult::NoMatch))
139 }
140
141 #[test]
142 fn ok_does_not_match_result_with_err() -> Result<()> {
143 let matcher = ok(eq(1));
144 let value: std::result::Result<i32, i32> = Err(1);
145
146 let result = matcher.matches(value);
147
148 verify_that!(result, eq(MatcherResult::NoMatch))
149 }
150
151 #[test]
152 fn ok_matches_result_with_value_by_ref() -> Result<()> {
153 let result: std::result::Result<String, String> = Ok("123".into());
154 verify_that!(result, ok(eq("123")))
155 }
156
157 #[test]
158 fn ok_does_not_match_result_with_wrong_value_by_ref() -> Result<()> {
159 let result: std::result::Result<String, String> = Ok("321".into());
160 verify_that!(result, not(ok(eq("123"))))
161 }
162
163 #[test]
164 fn ok_does_not_match_result_with_err_by_ref() -> Result<()> {
165 let result: std::result::Result<String, String> = Err("123".into());
166 verify_that!(result, not(ok(eq("123"))))
167 }
168
169 #[test]
170 fn ok_full_error_message() -> Result<()> {
171 let result = verify_that!(Ok::<i32, i32>(1), ok(eq(2)));
172
173 verify_that!(
174 result,
175 err(displays_as(contains_substring(indoc!(
176 "
177 Value of: Ok::<i32, i32>(1)
178 Expected: is a success containing a value, which is equal to 2
179 Actual: Ok(1),
180 which is a success
181 which isn't equal to 2
182 "
183 ))))
184 )
185 }
186
187 #[test]
188 fn ok_describe_match() -> Result<()> {
189 let matcher = ok(eq(1));
190 verify_that!(
191 Matcher::<std::result::Result<i32, i32>>::describe(&matcher, MatcherResult::Match),
192 displays_as(eq("is a success containing a value, which is equal to 1"))
193 )
194 }
195
196 #[test]
197 fn ok_describe_no_match() -> Result<()> {
198 let matcher = ok(eq(1));
199 verify_that!(
200 Matcher::<std::result::Result<i32, i32>>::describe(&matcher, MatcherResult::NoMatch),
201 displays_as(eq("is an error or a success containing a value, which isn't equal to 1"))
202 )
203 }
204
205 #[test]
206 fn ok_describe_match_by_ref() -> Result<()> {
207 let matcher = ok(eq(&1));
208 verify_that!(
209 Matcher::<&std::result::Result<i32, String>>::describe(&matcher, MatcherResult::Match),
210 displays_as(eq("is a success containing a value, which is equal to 1"))
211 )
212 }
213
214 #[test]
215 fn ok_describe_no_match_by_ref() -> Result<()> {
216 let matcher = ok(eq(&1));
217 verify_that!(
218 Matcher::<&std::result::Result<i32, String>>::describe(
219 &matcher,
220 MatcherResult::NoMatch
221 ),
222 displays_as(eq("is an error or a success containing a value, which isn't equal to 1"))
223 )
224 }
225
226 #[test]
227 fn ok_explain_match_ok_success() -> Result<()> {
228 let actual = Ok(1);
229 let matcher = ok(eq(1));
230
231 verify_that!(
232 Matcher::<std::result::Result<i32, i32>>::explain_match(&matcher, actual),
233 displays_as(eq("which is a success\n which is equal to 1"))
234 )
235 }
236
237 #[test]
238 fn ok_explain_match_ok_fail() -> Result<()> {
239 let actual = Ok(1);
240 let matcher = ok(eq(2));
241
242 verify_that!(
243 Matcher::<std::result::Result<i32, i32>>::explain_match(&matcher, actual),
244 displays_as(eq("which is a success\n which isn't equal to 2"))
245 )
246 }
247
248 #[test]
249 fn ok_explain_match_ok_err() -> Result<()> {
250 let actual = Err(1);
251 let matcher = ok(eq(2));
252
253 verify_that!(
254 Matcher::<std::result::Result<i32, i32>>::explain_match(&matcher, actual),
255 displays_as(eq("which is an error"))
256 )
257 }
258
259 #[test]
260 fn ok_explain_match_ok_success_by_ref() -> Result<()> {
261 let actual = Ok("123".to_string());
262 let matcher = ok(eq("123"));
263
264 verify_that!(
265 Matcher::<&std::result::Result<String, String>>::explain_match(&matcher, &actual),
266 displays_as(eq("which is a success\n which is equal to \"123\""))
267 )
268 }
269
270 #[test]
271 fn ok_explain_match_ok_fail_by_ref() -> Result<()> {
272 let actual = Ok("321".to_string());
273 let matcher = ok(eq("123"));
274
275 verify_that!(
276 Matcher::<&std::result::Result<String, String>>::explain_match(&matcher, &actual),
277 displays_as(eq("which is a success\n which isn't equal to \"123\""))
278 )
279 }
280
281 #[test]
282 fn ok_explain_match_ok_err_by_ref() -> Result<()> {
283 let actual = Err("123".to_string());
284 let matcher = ok(eq("123"));
285
286 verify_that!(
287 Matcher::<&std::result::Result<String, String>>::explain_match(&matcher, &actual),
288 displays_as(eq("which is an error"))
289 )
290 }
291}