1 // Copyright (c) 2018 The predicates-rs Project Developers.
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8
9 use std::fmt;
10
11 use crate::reflection;
12 use crate::utils;
13 use crate::Predicate;
14
15 /// Predicate that checks for empty strings.
16 ///
17 /// This is created by `predicates::str::is_empty`.
18 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
19 pub struct IsEmptyPredicate {}
20
21 impl Predicate<str> for IsEmptyPredicate {
eval(&self, variable: &str) -> bool22 fn eval(&self, variable: &str) -> bool {
23 variable.is_empty()
24 }
25
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>26 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
27 utils::default_find_case(self, expected, variable)
28 }
29 }
30
31 impl reflection::PredicateReflection for IsEmptyPredicate {}
32
33 impl fmt::Display for IsEmptyPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 write!(f, "var.is_empty()")
36 }
37 }
38
39 /// Creates a new `Predicate` that ensures a str is empty
40 ///
41 /// # Examples
42 ///
43 /// ```
44 /// use predicates::prelude::*;
45 ///
46 /// let predicate_fn = predicate::str::is_empty();
47 /// assert_eq!(true, predicate_fn.eval(""));
48 /// assert_eq!(false, predicate_fn.eval("Food World"));
49 /// ```
is_empty() -> IsEmptyPredicate50 pub fn is_empty() -> IsEmptyPredicate {
51 IsEmptyPredicate {}
52 }
53
54 /// Predicate checks start of str
55 ///
56 /// This is created by `predicates::str::starts_with`.
57 #[derive(Debug, Clone, PartialEq, Eq)]
58 pub struct StartsWithPredicate {
59 pattern: String,
60 }
61
62 impl Predicate<str> for StartsWithPredicate {
eval(&self, variable: &str) -> bool63 fn eval(&self, variable: &str) -> bool {
64 variable.starts_with(&self.pattern)
65 }
66
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>67 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
68 utils::default_find_case(self, expected, variable)
69 }
70 }
71
72 impl reflection::PredicateReflection for StartsWithPredicate {}
73
74 impl fmt::Display for StartsWithPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 write!(f, "var.starts_with({:?})", self.pattern)
77 }
78 }
79
80 /// Creates a new `Predicate` that ensures a str starts with `pattern`
81 ///
82 /// # Examples
83 ///
84 /// ```
85 /// use predicates::prelude::*;
86 ///
87 /// let predicate_fn = predicate::str::starts_with("Hello");
88 /// assert_eq!(true, predicate_fn.eval("Hello World"));
89 /// assert_eq!(false, predicate_fn.eval("Goodbye World"));
90 /// ```
starts_with<P>(pattern: P) -> StartsWithPredicate where P: Into<String>,91 pub fn starts_with<P>(pattern: P) -> StartsWithPredicate
92 where
93 P: Into<String>,
94 {
95 StartsWithPredicate {
96 pattern: pattern.into(),
97 }
98 }
99
100 /// Predicate checks end of str
101 ///
102 /// This is created by `predicates::str::ends_with`.
103 #[derive(Debug, Clone, PartialEq, Eq)]
104 pub struct EndsWithPredicate {
105 pattern: String,
106 }
107
108 impl Predicate<str> for EndsWithPredicate {
eval(&self, variable: &str) -> bool109 fn eval(&self, variable: &str) -> bool {
110 variable.ends_with(&self.pattern)
111 }
112
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>113 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
114 utils::default_find_case(self, expected, variable)
115 }
116 }
117
118 impl reflection::PredicateReflection for EndsWithPredicate {}
119
120 impl fmt::Display for EndsWithPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 write!(f, "var.ends_with({:?})", self.pattern)
123 }
124 }
125
126 /// Creates a new `Predicate` that ensures a str ends with `pattern`
127 ///
128 /// # Examples
129 ///
130 /// ```
131 /// use predicates::prelude::*;
132 ///
133 /// let predicate_fn = predicate::str::ends_with("World");
134 /// assert_eq!(true, predicate_fn.eval("Hello World"));
135 /// assert_eq!(false, predicate_fn.eval("Hello Moon"));
136 /// ```
ends_with<P>(pattern: P) -> EndsWithPredicate where P: Into<String>,137 pub fn ends_with<P>(pattern: P) -> EndsWithPredicate
138 where
139 P: Into<String>,
140 {
141 EndsWithPredicate {
142 pattern: pattern.into(),
143 }
144 }
145
146 /// Predicate that checks for patterns.
147 ///
148 /// This is created by `predicates::str:contains`.
149 #[derive(Debug, Clone, PartialEq, Eq)]
150 pub struct ContainsPredicate {
151 pattern: String,
152 }
153
154 impl ContainsPredicate {
155 /// Require a specific count of matches.
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// use predicates::prelude::*;
161 ///
162 /// let predicate_fn = predicate::str::contains("Two").count(2);
163 /// assert_eq!(true, predicate_fn.eval("One Two Three Two One"));
164 /// assert_eq!(false, predicate_fn.eval("One Two Three"));
165 /// ```
count(self, count: usize) -> MatchesPredicate166 pub fn count(self, count: usize) -> MatchesPredicate {
167 MatchesPredicate {
168 pattern: self.pattern,
169 count,
170 }
171 }
172 }
173
174 impl Predicate<str> for ContainsPredicate {
eval(&self, variable: &str) -> bool175 fn eval(&self, variable: &str) -> bool {
176 variable.contains(&self.pattern)
177 }
178
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>179 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
180 utils::default_find_case(self, expected, variable)
181 }
182 }
183
184 impl reflection::PredicateReflection for ContainsPredicate {}
185
186 impl fmt::Display for ContainsPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 write!(f, "var.contains({:?})", self.pattern)
189 }
190 }
191
192 /// Predicate that checks for repeated patterns.
193 ///
194 /// This is created by `predicates::str::contains(...).count`.
195 #[derive(Debug, Clone, PartialEq, Eq)]
196 pub struct MatchesPredicate {
197 pattern: String,
198 count: usize,
199 }
200
201 impl Predicate<str> for MatchesPredicate {
eval(&self, variable: &str) -> bool202 fn eval(&self, variable: &str) -> bool {
203 variable.matches(&self.pattern).count() == self.count
204 }
205
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>206 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
207 let actual_count = variable.matches(&self.pattern).count();
208 let result = self.count == actual_count;
209 if result == expected {
210 Some(
211 reflection::Case::new(Some(self), result)
212 .add_product(reflection::Product::new("actual count", actual_count)),
213 )
214 } else {
215 None
216 }
217 }
218 }
219
220 impl reflection::PredicateReflection for MatchesPredicate {
parameters<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Parameter<'a>> + 'a>221 fn parameters<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Parameter<'a>> + 'a> {
222 let params = vec![reflection::Parameter::new("count", &self.count)];
223 Box::new(params.into_iter())
224 }
225 }
226
227 impl fmt::Display for MatchesPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result228 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229 write!(f, "var.contains({})", self.pattern)
230 }
231 }
232
233 /// Creates a new `Predicate` that ensures a str contains `pattern`
234 ///
235 /// # Examples
236 ///
237 /// ```
238 /// use predicates::prelude::*;
239 ///
240 /// let predicate_fn = predicate::str::contains("Two");
241 /// assert_eq!(true, predicate_fn.eval("One Two Three"));
242 /// assert_eq!(false, predicate_fn.eval("Four Five Six"));
243 /// ```
contains<P>(pattern: P) -> ContainsPredicate where P: Into<String>,244 pub fn contains<P>(pattern: P) -> ContainsPredicate
245 where
246 P: Into<String>,
247 {
248 ContainsPredicate {
249 pattern: pattern.into(),
250 }
251 }
252