asserting/result/
mod.rs

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