1use crate::assertions::{AssertStringContainsAnyOf, AssertStringPattern};
10use crate::expectations::{StringContains, StringContainsAnyOf, StringEndsWith, StringStartWith};
11use crate::prelude::DefinedOrderProperty;
12use crate::properties::{IsEmptyProperty, LengthProperty};
13use crate::spec::{Expectation, Expression, FailingStrategy, Spec};
14use crate::std::fmt::Debug;
15use crate::std::str::Chars;
16#[cfg(not(feature = "std"))]
17use alloc::{format, string::String};
18
19impl IsEmptyProperty for &str {
20 fn is_empty_property(&self) -> bool {
21 self.is_empty()
22 }
23}
24
25impl LengthProperty for &str {
26 fn length_property(&self) -> usize {
27 self.len()
28 }
29}
30
31impl IsEmptyProperty for String {
32 fn is_empty_property(&self) -> bool {
33 self.is_empty()
34 }
35}
36
37impl LengthProperty for String {
38 fn length_property(&self) -> usize {
39 self.len()
40 }
41}
42
43#[cfg(feature = "std")]
44mod os_string {
45 use crate::properties::{IsEmptyProperty, LengthProperty};
46 use crate::std::ffi::{OsStr, OsString};
47
48 impl IsEmptyProperty for OsString {
49 fn is_empty_property(&self) -> bool {
50 self.is_empty()
51 }
52 }
53
54 impl LengthProperty for OsString {
55 fn length_property(&self) -> usize {
56 self.len()
57 }
58 }
59
60 impl IsEmptyProperty for &OsStr {
61 fn is_empty_property(&self) -> bool {
62 self.is_empty()
63 }
64 }
65
66 impl LengthProperty for &OsStr {
67 fn length_property(&self) -> usize {
68 self.len()
69 }
70 }
71}
72
73#[cfg(feature = "std")]
74mod c_string {
75 use crate::properties::IsEmptyProperty;
76 use crate::std::ffi::{CStr, CString};
77
78 impl IsEmptyProperty for CString {
79 fn is_empty_property(&self) -> bool {
80 self.is_empty()
81 }
82 }
83
84 impl IsEmptyProperty for &CStr {
85 fn is_empty_property(&self) -> bool {
86 self.is_empty()
87 }
88 }
89}
90
91impl DefinedOrderProperty for Chars<'_> {}
92
93impl<'a, S, R> AssertStringPattern<&'a str> for Spec<'a, S, R>
99where
100 S: 'a + AsRef<str> + Debug,
101 R: FailingStrategy,
102{
103 fn contains(self, pattern: &'a str) -> Self {
104 self.expecting(StringContains { expected: pattern })
105 }
106
107 fn starts_with(self, pattern: &str) -> Self {
108 self.expecting(StringStartWith { expected: pattern })
109 }
110
111 fn ends_with(self, pattern: &str) -> Self {
112 self.expecting(StringEndsWith { expected: pattern })
113 }
114}
115
116impl<'a, S, R> AssertStringPattern<String> for Spec<'a, S, R>
117where
118 S: 'a + AsRef<str> + Debug,
119 R: FailingStrategy,
120{
121 fn contains(self, pattern: String) -> Self {
122 self.expecting(StringContains { expected: pattern })
123 }
124
125 fn starts_with(self, pattern: String) -> Self {
126 self.expecting(StringStartWith { expected: pattern })
127 }
128
129 fn ends_with(self, pattern: String) -> Self {
130 self.expecting(StringEndsWith { expected: pattern })
131 }
132}
133
134impl<'a, S, R> AssertStringPattern<char> for Spec<'a, S, R>
135where
136 S: 'a + AsRef<str> + Debug,
137 R: FailingStrategy,
138{
139 fn contains(self, expected: char) -> Self {
140 self.expecting(StringContains { expected })
141 }
142
143 fn starts_with(self, expected: char) -> Self {
144 self.expecting(StringStartWith { expected })
145 }
146
147 fn ends_with(self, pattern: char) -> Self {
148 self.expecting(StringEndsWith { expected: pattern })
149 }
150}
151
152impl<S> Expectation<S> for StringContains<&str>
153where
154 S: AsRef<str> + Debug,
155{
156 fn test(&mut self, subject: &S) -> bool {
157 subject.as_ref().contains(self.expected)
158 }
159
160 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
161 format!(
162 "expected {expression} to contain {:?}\n but was: {actual:?}\n expected: {:?}",
163 self.expected, self.expected
164 )
165 }
166}
167
168impl<S> Expectation<S> for StringContains<String>
169where
170 S: AsRef<str> + Debug,
171{
172 fn test(&mut self, subject: &S) -> bool {
173 subject.as_ref().contains(&self.expected)
174 }
175
176 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
177 format!(
178 "expected {expression} to contain {:?}\n but was: {actual:?}\n expected: {:?}",
179 self.expected, self.expected
180 )
181 }
182}
183
184impl<S> Expectation<S> for StringContains<char>
185where
186 S: AsRef<str> + Debug,
187{
188 fn test(&mut self, subject: &S) -> bool {
189 subject.as_ref().contains(self.expected)
190 }
191
192 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
193 format!(
194 "expected {expression} to contain {:?}\n but was: {actual:?}\n expected: {:?}",
195 self.expected, self.expected
196 )
197 }
198}
199
200impl<S> Expectation<S> for StringStartWith<&str>
201where
202 S: AsRef<str> + Debug,
203{
204 fn test(&mut self, subject: &S) -> bool {
205 subject.as_ref().starts_with(self.expected)
206 }
207
208 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
209 format!(
210 "expected {expression} to start with {:?}\n but was: {actual:?}\n expected: {:?}",
211 self.expected, self.expected
212 )
213 }
214}
215
216impl<S> Expectation<S> for StringStartWith<String>
217where
218 S: AsRef<str> + Debug,
219{
220 fn test(&mut self, subject: &S) -> bool {
221 subject.as_ref().starts_with(&self.expected)
222 }
223
224 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
225 format!(
226 "expected {expression} to start with {:?}\n but was: {actual:?}\n expected: {:?}",
227 self.expected, self.expected
228 )
229 }
230}
231
232impl<S> Expectation<S> for StringStartWith<char>
233where
234 S: AsRef<str> + Debug,
235{
236 fn test(&mut self, subject: &S) -> bool {
237 subject.as_ref().starts_with(self.expected)
238 }
239
240 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
241 format!(
242 "expected {expression} to start with {:?}\n but was: {actual:?}\n expected: {:?}",
243 self.expected, self.expected
244 )
245 }
246}
247
248impl<S> Expectation<S> for StringEndsWith<&str>
249where
250 S: AsRef<str> + Debug,
251{
252 fn test(&mut self, subject: &S) -> bool {
253 subject.as_ref().ends_with(self.expected)
254 }
255
256 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
257 format!(
258 "expected {expression} to end with {:?}\n but was: {actual:?}\n expected: {:?}",
259 self.expected, self.expected
260 )
261 }
262}
263
264impl<S> Expectation<S> for StringEndsWith<String>
265where
266 S: AsRef<str> + Debug,
267{
268 fn test(&mut self, subject: &S) -> bool {
269 subject.as_ref().ends_with(&self.expected)
270 }
271
272 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
273 format!(
274 "expected {expression} to end with {:?}\n but was: {actual:?}\n expected: {:?}",
275 self.expected, self.expected
276 )
277 }
278}
279
280impl<S> Expectation<S> for StringEndsWith<char>
281where
282 S: AsRef<str> + Debug,
283{
284 fn test(&mut self, subject: &S) -> bool {
285 subject.as_ref().ends_with(self.expected)
286 }
287
288 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
289 format!(
290 "expected {expression} to end with {:?}\n but was: {actual:?}\n expected: {:?}",
291 self.expected, self.expected
292 )
293 }
294}
295
296impl<'a, S, R> AssertStringContainsAnyOf<&'a [char]> for Spec<'a, S, R>
303where
304 S: 'a + AsRef<str> + Debug,
305 R: FailingStrategy,
306{
307 fn contains_any_of(self, expected: &'a [char]) -> Self {
308 self.expecting(StringContainsAnyOf { expected })
309 }
310}
311
312impl<'a, S, R, const N: usize> AssertStringContainsAnyOf<[char; N]> for Spec<'a, S, R>
313where
314 S: 'a + AsRef<str> + Debug,
315 R: FailingStrategy,
316{
317 fn contains_any_of(self, expected: [char; N]) -> Self {
318 self.expecting(StringContainsAnyOf { expected })
319 }
320}
321
322impl<'a, S, R, const N: usize> AssertStringContainsAnyOf<&'a [char; N]> for Spec<'a, S, R>
323where
324 S: 'a + AsRef<str> + Debug,
325 R: FailingStrategy,
326{
327 fn contains_any_of(self, expected: &'a [char; N]) -> Self {
328 self.expecting(StringContainsAnyOf { expected })
329 }
330}
331
332impl<S> Expectation<S> for StringContainsAnyOf<&[char]>
333where
334 S: AsRef<str> + Debug,
335{
336 fn test(&mut self, subject: &S) -> bool {
337 subject.as_ref().contains(self.expected)
338 }
339
340 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
341 format!(
342 "expected {expression} to contain any of {:?}\n but was: {actual:?}\n expected: {:?}",
343 self.expected, self.expected
344 )
345 }
346}
347
348impl<S, const N: usize> Expectation<S> for StringContainsAnyOf<[char; N]>
349where
350 S: AsRef<str> + Debug,
351{
352 fn test(&mut self, subject: &S) -> bool {
353 subject.as_ref().contains(self.expected)
354 }
355
356 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
357 format!(
358 "expected {expression} to contain any of {:?}\n but was: {actual:?}\n expected: {:?}",
359 self.expected, self.expected
360 )
361 }
362}
363
364impl<S, const N: usize> Expectation<S> for StringContainsAnyOf<&[char; N]>
365where
366 S: AsRef<str> + Debug,
367{
368 fn test(&mut self, subject: &S) -> bool {
369 subject.as_ref().contains(self.expected)
370 }
371
372 fn message(&self, expression: Expression<'_>, actual: &S) -> String {
373 format!(
374 "expected {expression} to contain any of {:?}\n but was: {actual:?}\n expected: {:?}",
375 self.expected, self.expected
376 )
377 }
378}
379
380#[cfg(test)]
381mod tests;