1use crate::assertions::{
4 AssertBorrowedOptionValue, AssertHasValue, AssertOption, AssertOptionValue,
5};
6use crate::colored::{mark_missing, mark_unexpected};
7use crate::expectations::{has_value, is_none, is_some, HasValue, IsNone, IsSome};
8use crate::spec::{
9 DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec, Unknown,
10};
11use crate::std::fmt::Debug;
12use crate::std::{format, string::String};
13
14impl<S, R> AssertOption for Spec<'_, Option<S>, R>
15where
16 S: Debug,
17 R: FailingStrategy,
18{
19 fn is_some(self) -> Self {
20 self.expecting(is_some())
21 }
22
23 fn is_none(self) -> Self {
24 self.expecting(is_none())
25 }
26}
27
28impl<S, R> AssertOption for Spec<'_, &Option<S>, R>
29where
30 S: Debug,
31 R: FailingStrategy,
32{
33 fn is_some(self) -> Self {
34 self.expecting(is_some())
35 }
36
37 fn is_none(self) -> Self {
38 self.expecting(is_none())
39 }
40}
41
42impl<'a, T, R> AssertOptionValue<'a, T, R> for Spec<'a, Option<T>, R>
43where
44 R: FailingStrategy,
45{
46 fn some(self) -> Spec<'a, T, R> {
47 self.mapping(|subject| match subject {
48 None => {
49 panic!("expected the subject to be `Some(_)`, but was `None`")
50 },
51 Some(value) => value,
52 })
53 }
54}
55
56impl<'a, T, R> AssertBorrowedOptionValue<'a, T, R> for Spec<'a, &'a Option<T>, R>
57where
58 R: FailingStrategy,
59{
60 fn some(self) -> Spec<'a, &'a T, R> {
61 self.mapping(|subject| match subject {
62 None => {
63 panic!("expected the subject to be `Some(_)`, but was `None`")
64 },
65 Some(value) => value,
66 })
67 }
68}
69
70impl<S, E, R> AssertHasValue<E> for Spec<'_, Option<S>, R>
71where
72 S: PartialEq<E> + Debug,
73 E: Debug,
74 R: FailingStrategy,
75{
76 fn has_value(self, expected: E) -> Self {
77 self.expecting(has_value(expected))
78 }
79}
80
81impl<S, E, R> AssertHasValue<E> for Spec<'_, &Option<S>, R>
82where
83 S: PartialEq<E> + Debug,
84 E: Debug,
85 R: FailingStrategy,
86{
87 fn has_value(self, expected: E) -> Self {
88 self.expecting(has_value(expected))
89 }
90}
91
92impl<T> Expectation<Option<T>> for IsSome
93where
94 T: Debug,
95{
96 fn test(&mut self, subject: &Option<T>) -> bool {
97 subject.is_some()
98 }
99
100 fn message(
101 &self,
102 expression: &Expression<'_>,
103 actual: &Option<T>,
104 _inverted: bool,
105 format: &DiffFormat,
106 ) -> String {
107 let expected = Some(Unknown);
108 let marked_actual = mark_unexpected(actual, format);
109 let marked_expected = mark_missing(&expected, format);
110 format!(
111 "expected {expression} to be {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}"
112 )
113 }
114}
115
116impl<T> Expectation<&Option<T>> for IsSome
117where
118 T: Debug,
119{
120 fn test(&mut self, subject: &&Option<T>) -> bool {
121 <Self as Expectation<Option<T>>>::test(self, subject)
122 }
123
124 fn message(
125 &self,
126 expression: &Expression<'_>,
127 actual: &&Option<T>,
128 inverted: bool,
129 format: &DiffFormat,
130 ) -> String {
131 <Self as Expectation<Option<T>>>::message(self, expression, actual, inverted, format)
132 }
133}
134
135impl<T> Expectation<Option<T>> for IsNone
136where
137 T: Debug,
138{
139 fn test(&mut self, subject: &Option<T>) -> bool {
140 subject.is_none()
141 }
142
143 fn message(
144 &self,
145 expression: &Expression<'_>,
146 actual: &Option<T>,
147 _inverted: bool,
148 format: &DiffFormat,
149 ) -> String {
150 let expected = None::<Unknown>;
151 let marked_actual = mark_unexpected(actual, format);
152 let marked_expected = mark_missing(&expected, format);
153 format!(
154 "expected {expression} to be {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}"
155 )
156 }
157}
158
159impl<T> Expectation<&Option<T>> for IsNone
160where
161 T: Debug,
162{
163 fn test(&mut self, subject: &&Option<T>) -> bool {
164 <Self as Expectation<Option<T>>>::test(self, subject)
165 }
166
167 fn message(
168 &self,
169 expression: &Expression<'_>,
170 actual: &&Option<T>,
171 inverted: bool,
172 format: &DiffFormat,
173 ) -> String {
174 <Self as Expectation<Option<T>>>::message(self, expression, actual, inverted, format)
175 }
176}
177
178impl<T, E> Expectation<Option<T>> for HasValue<E>
179where
180 T: PartialEq<E> + Debug,
181 E: Debug,
182{
183 fn test(&mut self, subject: &Option<T>) -> bool {
184 subject
185 .as_ref()
186 .is_some_and(|value| value == &self.expected)
187 }
188
189 fn message(
190 &self,
191 expression: &Expression<'_>,
192 actual: &Option<T>,
193 inverted: bool,
194 format: &DiffFormat,
195 ) -> String {
196 let not = if inverted { "not " } else { "" };
197 let expected = &self.expected;
198 let marked_actual = mark_unexpected(actual, format);
199 let marked_expected = mark_missing(&Some(expected), format);
200 format!("expected {expression} to be some {not}containing {expected:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}")
201 }
202}
203
204impl<E> Invertible for HasValue<E> {}
205
206impl<T, E> Expectation<&Option<T>> for HasValue<E>
207where
208 T: PartialEq<E> + Debug,
209 E: Debug,
210{
211 fn test(&mut self, subject: &&Option<T>) -> bool {
212 <Self as Expectation<Option<T>>>::test(self, subject)
213 }
214
215 fn message(
216 &self,
217 expression: &Expression<'_>,
218 actual: &&Option<T>,
219 inverted: bool,
220 format: &DiffFormat,
221 ) -> String {
222 <Self as Expectation<Option<T>>>::message(self, expression, actual, inverted, format)
223 }
224}
225
226#[cfg(test)]
227mod tests;