1use std::fmt::Debug;
19
20pub fn expect<T>(value: T) -> Expect<T> {
21 Expect(value)
22}
23
24pub struct Expect<T>(pub T);
25pub struct Not<T>(pub T);
26
27impl<T> Expect<T> {
28 #[allow(clippy::should_implement_trait)]
29 pub fn not(self) -> Not<T> {
30 Not(self.0)
31 }
32 pub fn value(&self) -> &T {
33 &self.0
34 }
35 pub fn into_inner(self) -> T {
36 self.0
37 }
38}
39
40impl<T> Not<T> {
41 pub fn value(&self) -> &T {
42 &self.0
43 }
44}
45
46impl<T: PartialEq + Debug> Expect<T> {
49 pub fn to_be(self, expected: T) -> Self {
50 assert!(
51 self.0 == expected,
52 "expected {:?} to equal {:?}",
53 self.0,
54 expected
55 );
56 self
57 }
58 pub fn to_equal(self, expected: T) -> Self {
59 self.to_be(expected)
60 }
61}
62
63impl<T: PartialEq + Debug> Not<T> {
64 pub fn to_be(self, expected: T) -> Self {
65 assert!(
66 self.0 != expected,
67 "expected {:?} NOT to equal {:?}",
68 self.0,
69 expected
70 );
71 self
72 }
73 pub fn to_equal(self, expected: T) -> Self {
74 self.to_be(expected)
75 }
76}
77
78impl Expect<bool> {
81 pub fn to_be_true(self) -> Self {
82 assert!(self.0, "expected true, got false");
83 self
84 }
85 pub fn to_be_false(self) -> Self {
86 assert!(!self.0, "expected false, got true");
87 self
88 }
89}
90
91impl<T: PartialOrd + Debug> Expect<T> {
94 pub fn to_be_greater_than(self, other: T) -> Self {
95 assert!(self.0 > other, "expected {:?} > {:?}", self.0, other);
96 self
97 }
98 pub fn to_be_less_than(self, other: T) -> Self {
99 assert!(self.0 < other, "expected {:?} < {:?}", self.0, other);
100 self
101 }
102 pub fn to_be_at_least(self, other: T) -> Self {
103 assert!(self.0 >= other, "expected {:?} >= {:?}", self.0, other);
104 self
105 }
106 pub fn to_be_at_most(self, other: T) -> Self {
107 assert!(self.0 <= other, "expected {:?} <= {:?}", self.0, other);
108 self
109 }
110}
111
112impl Expect<&str> {
115 pub fn to_contain(self, needle: &str) -> Self {
116 assert!(
117 self.0.contains(needle),
118 "expected `{}` to contain `{}`",
119 self.0,
120 needle
121 );
122 self
123 }
124 pub fn to_start_with(self, prefix: &str) -> Self {
125 assert!(
126 self.0.starts_with(prefix),
127 "expected `{}` to start with `{}`",
128 self.0,
129 prefix
130 );
131 self
132 }
133 pub fn to_end_with(self, suffix: &str) -> Self {
134 assert!(
135 self.0.ends_with(suffix),
136 "expected `{}` to end with `{}`",
137 self.0,
138 suffix
139 );
140 self
141 }
142 pub fn to_match(self, regex: &str) -> Self {
143 let re = regex::Regex::new(regex).expect("invalid regex");
144 assert!(
145 re.is_match(self.0),
146 "expected `{}` to match /{regex}/",
147 self.0
148 );
149 self
150 }
151}
152
153impl Expect<String> {
154 pub fn to_contain(self, needle: &str) -> Self {
155 assert!(
156 self.0.contains(needle),
157 "expected `{}` to contain `{needle}`",
158 self.0
159 );
160 self
161 }
162 pub fn to_start_with(self, prefix: &str) -> Self {
163 assert!(
164 self.0.starts_with(prefix),
165 "expected `{}` to start with `{prefix}`",
166 self.0
167 );
168 self
169 }
170 pub fn to_end_with(self, suffix: &str) -> Self {
171 assert!(
172 self.0.ends_with(suffix),
173 "expected `{}` to end with `{suffix}`",
174 self.0
175 );
176 self
177 }
178 pub fn to_match(self, regex: &str) -> Self {
179 let re = regex::Regex::new(regex).expect("invalid regex");
180 assert!(
181 re.is_match(&self.0),
182 "expected `{}` to match /{regex}/",
183 self.0
184 );
185 self
186 }
187}
188
189impl<T: Debug + PartialEq> Expect<Vec<T>> {
192 pub fn to_have_length(self, len: usize) -> Self {
193 assert_eq!(
194 self.0.len(),
195 len,
196 "expected length {len}, got {}",
197 self.0.len()
198 );
199 self
200 }
201 pub fn to_contain(self, item: T) -> Self {
202 assert!(
203 self.0.iter().any(|v| v == &item),
204 "expected {:?} to contain {:?}",
205 self.0,
206 item
207 );
208 self
209 }
210 pub fn to_be_empty(self) -> Self {
211 assert!(self.0.is_empty(), "expected empty, got {:?}", self.0);
212 self
213 }
214}
215
216impl<T: Debug> Expect<Option<T>> {
219 pub fn to_be_some(self) -> Self {
220 assert!(self.0.is_some(), "expected Some(_), got None");
221 self
222 }
223 pub fn to_be_none(self) -> Self {
224 assert!(self.0.is_none(), "expected None, got {:?}", self.0);
225 self
226 }
227}
228
229impl<T: Debug, E: Debug> Expect<Result<T, E>> {
232 pub fn to_be_ok(self) -> Self {
233 assert!(self.0.is_ok(), "expected Ok, got {:?}", self.0);
234 self
235 }
236 pub fn to_be_err(self) -> Self {
237 assert!(self.0.is_err(), "expected Err, got {:?}", self.0);
238 self
239 }
240}