Skip to main content

asserting/result/
mod.rs

1//! Implementation of assertions for `Result` values.
2
3use crate::assertions::{
4    AssertHasError, AssertHasErrorMessage, AssertHasValue, AssertResult, AssertResultValue,
5};
6use crate::colored::{mark_missing, mark_unexpected};
7use crate::expectations::{
8    HasError, HasValue, IsErr, IsOk, has_error, has_value, is_equal_to, is_err, is_ok,
9};
10use crate::spec::{
11    DiffFormat, Expectation, Expecting, Expression, FailingStrategy, Invertible, Spec, Unknown,
12};
13use crate::std::fmt::{Debug, Display};
14use crate::std::{
15    format,
16    string::{String, ToString},
17};
18
19impl<T, E, R> AssertResult for Spec<'_, Result<T, E>, R>
20where
21    T: Debug,
22    E: Debug,
23    R: FailingStrategy,
24{
25    fn is_ok(self) -> Self {
26        self.expecting(is_ok())
27    }
28
29    fn is_err(self) -> Self {
30        self.expecting(is_err())
31    }
32}
33
34impl<T, E, R> AssertResult for Spec<'_, &Result<T, E>, R>
35where
36    T: Debug,
37    E: Debug,
38    R: FailingStrategy,
39{
40    fn is_ok(self) -> Self {
41        self.expecting(is_ok())
42    }
43
44    fn is_err(self) -> Self {
45        self.expecting(is_err())
46    }
47}
48
49impl<'a, T, E, R> AssertResultValue for Spec<'a, Result<T, E>, R>
50where
51    T: Debug,
52    E: Debug,
53{
54    type Ok = Spec<'a, T, R>;
55    type Err = Spec<'a, E, R>;
56
57    fn ok(self) -> Self::Ok {
58        self.mapping(|subject| match subject {
59            Ok(value) => value,
60            Err(error) => {
61                panic!("expected the subject to be `Ok(_)`, but was `Err({error:?})`")
62            },
63        })
64    }
65
66    fn err(self) -> Self::Err {
67        self.mapping(|subject| match subject {
68            Ok(value) => {
69                panic!("expected the subject to be `Err(_)`, but was `Ok({value:?})`")
70            },
71            Err(error) => error,
72        })
73    }
74}
75
76impl<'a, T, E, R> AssertResultValue for Spec<'a, &'a Result<T, E>, R>
77where
78    T: Debug,
79    E: Debug,
80{
81    type Ok = Spec<'a, &'a T, R>;
82    type Err = Spec<'a, &'a E, R>;
83
84    fn ok(self) -> Self::Ok {
85        self.mapping(|subject| match subject {
86            Ok(value) => value,
87            Err(error) => {
88                panic!("expected the subject to be `Ok(_)`, but was `Err({error:?})`")
89            },
90        })
91    }
92
93    fn err(self) -> Self::Err {
94        self.mapping(|subject| match subject {
95            Ok(value) => {
96                panic!("expected the subject to be `Err(_)`, but was `Ok({value:?})`")
97            },
98            Err(error) => error,
99        })
100    }
101}
102
103impl<T, E, X, R> AssertHasValue<X> for Spec<'_, Result<T, E>, R>
104where
105    T: PartialEq<X> + Debug,
106    E: Debug,
107    X: Debug,
108    R: FailingStrategy,
109{
110    fn has_value(self, expected: X) -> Self {
111        self.expecting(has_value(expected))
112    }
113}
114
115impl<T, E, X, R> AssertHasValue<X> for Spec<'_, &Result<T, E>, R>
116where
117    T: PartialEq<X> + Debug,
118    E: Debug,
119    X: Debug,
120    R: FailingStrategy,
121{
122    fn has_value(self, expected: X) -> Self {
123        self.expecting(has_value(expected))
124    }
125}
126
127impl<T, E, X, R> AssertHasError<X> for Spec<'_, Result<T, E>, R>
128where
129    T: Debug,
130    E: PartialEq<X> + Debug,
131    X: Debug,
132    R: FailingStrategy,
133{
134    fn has_error(self, expected: X) -> Self {
135        self.expecting(has_error(expected))
136    }
137}
138
139impl<T, E, X, R> AssertHasError<X> for Spec<'_, &Result<T, E>, R>
140where
141    T: Debug,
142    E: PartialEq<X> + Debug,
143    X: Debug,
144    R: FailingStrategy,
145{
146    fn has_error(self, expected: X) -> Self {
147        self.expecting(has_error(expected))
148    }
149}
150
151impl<'a, T, E, X, R> AssertHasErrorMessage<X> for Spec<'a, Result<T, E>, R>
152where
153    T: Debug,
154    E: Display,
155    X: Debug,
156    String: PartialEq<X>,
157    R: FailingStrategy,
158{
159    type ErrorMessage = Spec<'a, String, R>;
160
161    fn has_error_message(self, expected: X) -> Self::ErrorMessage {
162        self.mapping(|result| match result {
163            Ok(value) => panic!(
164                r"expected the subject to be `Err(_)` with message {expected:?}, but was `Ok({value:?})`"
165            ),
166            Err(error) => {
167                error.to_string()
168            },
169        }).expecting(is_equal_to(expected))
170    }
171}
172
173impl<'a, T, E, X, R> AssertHasErrorMessage<X> for Spec<'a, &Result<T, E>, R>
174where
175    T: Debug,
176    E: Display,
177    X: Debug,
178    String: PartialEq<X>,
179    R: FailingStrategy,
180{
181    type ErrorMessage = Spec<'a, String, R>;
182
183    fn has_error_message(self, expected: X) -> Self::ErrorMessage {
184        self.mapping(|result| match result {
185            Ok(value) => panic!(
186                r"expected the subject to be `Err(_)` with message {expected:?}, but was `Ok({value:?})`"
187            ),
188            Err(error) => {
189                error.to_string()
190            },
191        }).expecting(is_equal_to(expected))
192    }
193}
194
195impl<T, E> Expectation<Result<T, E>> for IsOk
196where
197    T: Debug,
198    E: Debug,
199{
200    fn test(&mut self, subject: &Result<T, E>) -> bool {
201        subject.is_ok()
202    }
203
204    fn message(
205        &self,
206        expression: &Expression<'_>,
207        actual: &Result<T, E>,
208        _inverted: bool,
209        format: &DiffFormat,
210    ) -> String {
211        let expected = Ok::<_, Unknown>(Unknown);
212        let marked_actual = mark_unexpected(actual, format);
213        let marked_expected = mark_missing(&expected, format);
214        format!(
215            "expected {expression} to be {expected:?}\n   but was: {marked_actual}\n  expected: {marked_expected}"
216        )
217    }
218}
219
220impl<T, E> Expectation<Result<T, E>> for IsErr
221where
222    T: Debug,
223    E: Debug,
224{
225    fn test(&mut self, subject: &Result<T, E>) -> bool {
226        subject.is_err()
227    }
228
229    fn message(
230        &self,
231        expression: &Expression<'_>,
232        actual: &Result<T, E>,
233        _inverted: bool,
234        format: &DiffFormat,
235    ) -> String {
236        let expected = Err::<Unknown, Unknown>(Unknown);
237        let marked_actual = mark_unexpected(actual, format);
238        let marked_expected = mark_missing(&expected, format);
239        format!(
240            "expected {expression} to be {expected:?}\n   but was: {marked_actual}\n  expected: {marked_expected}"
241        )
242    }
243}
244
245impl<T, E> Expectation<&Result<T, E>> for IsOk
246where
247    T: Debug,
248    E: Debug,
249{
250    fn test(&mut self, subject: &&Result<T, E>) -> bool {
251        <Self as Expectation<Result<T, E>>>::test(self, subject)
252    }
253
254    fn message(
255        &self,
256        expression: &Expression<'_>,
257        actual: &&Result<T, E>,
258        inverted: bool,
259        format: &DiffFormat,
260    ) -> String {
261        <Self as Expectation<Result<T, E>>>::message(self, expression, actual, inverted, format)
262    }
263}
264
265impl<T, E> Expectation<&Result<T, E>> for IsErr
266where
267    T: Debug,
268    E: Debug,
269{
270    fn test(&mut self, subject: &&Result<T, E>) -> bool {
271        <Self as Expectation<Result<T, E>>>::test(self, subject)
272    }
273
274    fn message(
275        &self,
276        expression: &Expression<'_>,
277        actual: &&Result<T, E>,
278        inverted: bool,
279        format: &DiffFormat,
280    ) -> String {
281        <Self as Expectation<Result<T, E>>>::message(self, expression, actual, inverted, format)
282    }
283}
284
285impl<T, E, X> Expectation<Result<T, E>> for HasValue<X>
286where
287    T: PartialEq<X> + Debug,
288    E: Debug,
289    X: Debug,
290{
291    fn test(&mut self, subject: &Result<T, E>) -> bool {
292        subject.as_ref().is_ok_and(|value| value == &self.expected)
293    }
294
295    fn message(
296        &self,
297        expression: &Expression<'_>,
298        actual: &Result<T, E>,
299        inverted: bool,
300        format: &DiffFormat,
301    ) -> String {
302        let not = if inverted { "not " } else { "" };
303        let expected = &self.expected;
304        let marked_actual = mark_unexpected(actual, format);
305        let marked_expected = mark_missing(&Ok::<_, E>(expected), format);
306        format!(
307            "expected {expression} to be ok {not}containing {expected:?}\n   but was: {marked_actual}\n  expected: {not}{marked_expected}"
308        )
309    }
310}
311
312impl<T, E, X> Expectation<&Result<T, E>> for HasValue<X>
313where
314    T: PartialEq<X> + Debug,
315    E: Debug,
316    X: Debug,
317{
318    fn test(&mut self, subject: &&Result<T, E>) -> bool {
319        <Self as Expectation<Result<T, E>>>::test(self, subject)
320    }
321
322    fn message(
323        &self,
324        expression: &Expression<'_>,
325        actual: &&Result<T, E>,
326        inverted: bool,
327        format: &DiffFormat,
328    ) -> String {
329        <Self as Expectation<Result<T, E>>>::message(self, expression, actual, inverted, format)
330    }
331}
332
333impl<T, E, X> Expectation<Result<T, E>> for HasError<X>
334where
335    T: Debug,
336    E: PartialEq<X> + Debug,
337    X: Debug,
338{
339    fn test(&mut self, subject: &Result<T, E>) -> bool {
340        subject.as_ref().is_err_and(|err| err == &self.expected)
341    }
342
343    fn message(
344        &self,
345        expression: &Expression<'_>,
346        actual: &Result<T, E>,
347        inverted: bool,
348        format: &DiffFormat,
349    ) -> String {
350        let not = if inverted { "not " } else { "" };
351        let expected = &self.expected;
352        let marked_actual = mark_unexpected(actual, format);
353        let marked_expected = mark_missing(&Err::<T, _>(expected), format);
354        format!(
355            "expected {expression} to be an error {not}containing {expected:?}\n   but was: {marked_actual}\n  expected: {not}{marked_expected}"
356        )
357    }
358}
359
360impl<X> Invertible for HasError<X> {}
361
362impl<T, E, X> Expectation<&Result<T, E>> for HasError<X>
363where
364    T: Debug,
365    E: PartialEq<X> + Debug,
366    X: Debug,
367{
368    fn test(&mut self, subject: &&Result<T, E>) -> bool {
369        <Self as Expectation<Result<T, E>>>::test(self, subject)
370    }
371
372    fn message(
373        &self,
374        expression: &Expression<'_>,
375        actual: &&Result<T, E>,
376        inverted: bool,
377        format: &DiffFormat,
378    ) -> String {
379        <Self as Expectation<Result<T, E>>>::message(self, expression, actual, inverted, format)
380    }
381}
382
383#[cfg(test)]
384mod tests;