predicates/str/
regex.rs
1use std::fmt;
10
11use crate::reflection;
12use crate::utils;
13use crate::Predicate;
14
15pub type RegexError = regex::Error;
17
18#[derive(Debug, Clone)]
22pub struct RegexPredicate {
23 re: regex::Regex,
24}
25
26impl RegexPredicate {
27 pub fn count(self, count: usize) -> RegexMatchesPredicate {
39 RegexMatchesPredicate { re: self.re, count }
40 }
41}
42
43impl Predicate<str> for RegexPredicate {
44 fn eval(&self, variable: &str) -> bool {
45 self.re.is_match(variable)
46 }
47
48 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
49 utils::default_find_case(self, expected, variable)
50 }
51}
52
53impl reflection::PredicateReflection for RegexPredicate {}
54
55impl fmt::Display for RegexPredicate {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 write!(f, "var.is_match({})", self.re)
58 }
59}
60
61#[derive(Debug, Clone)]
65pub struct RegexMatchesPredicate {
66 re: regex::Regex,
67 count: usize,
68}
69
70impl Predicate<str> for RegexMatchesPredicate {
71 fn eval(&self, variable: &str) -> bool {
72 self.re.find_iter(variable).count() == self.count
73 }
74
75 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
76 let actual_count = self.re.find_iter(variable).count();
77 let result = self.count == actual_count;
78 if result == expected {
79 Some(
80 reflection::Case::new(Some(self), result)
81 .add_product(reflection::Product::new("actual count", actual_count)),
82 )
83 } else {
84 None
85 }
86 }
87}
88
89impl reflection::PredicateReflection for RegexMatchesPredicate {
90 fn parameters<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Parameter<'a>> + 'a> {
91 let params = vec![reflection::Parameter::new("count", &self.count)];
92 Box::new(params.into_iter())
93 }
94}
95
96impl fmt::Display for RegexMatchesPredicate {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(f, "var.is_match({})", self.re)
99 }
100}
101
102pub fn is_match<S>(pattern: S) -> Result<RegexPredicate, RegexError>
114where
115 S: AsRef<str>,
116{
117 regex::Regex::new(pattern.as_ref()).map(|re| RegexPredicate { re })
118}