Skip to content

Commit c984772

Browse files
committed
feat(str): Specialized string predicates
Including - starts_with - ends_with - contains Unfortunately, we can't take pattern, so we're limited to `Into<String>`. The only thing missing to complete #25 is to add a `count` to `contains`. This would either be a number or a numeric predicate.
1 parent 956820a commit c984772

File tree

3 files changed

+131
-0
lines changed

3 files changed

+131
-0
lines changed

src/prelude.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub mod predicate {
2222
///
2323
/// This module contains predicates specific to string handling.
2424
pub mod str {
25+
pub use str::is_empty;
26+
pub use str::{contains, ends_with, starts_with};
27+
2528
#[cfg(feature = "difference")]
2629
pub use str::{diff, similar};
2730

src/str/basics.rs

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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 Predicate;
10+
11+
/// Predicate that checks for empty strings.
12+
///
13+
/// This is created by `predicates::str::is_empty`.
14+
#[derive(Copy, Clone, Debug)]
15+
pub struct IsEmptyPredicate {}
16+
17+
impl Predicate<str> for IsEmptyPredicate {
18+
fn eval(&self, variable: &str) -> bool {
19+
variable.is_empty()
20+
}
21+
}
22+
23+
/// Creates a new `Predicate` that ensures a str is empty
24+
///
25+
/// # Examples
26+
///
27+
/// ```
28+
/// use predicates::prelude::*;
29+
///
30+
/// let predicate_fn = predicate::str::is_empty();
31+
/// assert_eq!(true, predicate_fn.eval(""));
32+
/// assert_eq!(false, predicate_fn.eval("Food World"));
33+
/// ```
34+
pub fn is_empty() -> IsEmptyPredicate {
35+
IsEmptyPredicate {}
36+
}
37+
38+
#[derive(Copy, Clone, Debug)]
39+
enum PatternOp {
40+
StartsWith,
41+
EndsWith,
42+
Contains,
43+
}
44+
45+
/// Predicate that checks for patterns.
46+
///
47+
/// This is created by `predicates::str::{starts_with, ends_with, contains}`.
48+
#[derive(Clone, Debug)]
49+
pub struct PatternPredicate {
50+
pattern: String,
51+
op: PatternOp,
52+
}
53+
54+
impl Predicate<str> for PatternPredicate {
55+
fn eval(&self, variable: &str) -> bool {
56+
match self.op {
57+
PatternOp::StartsWith => variable.starts_with(&self.pattern),
58+
PatternOp::EndsWith => variable.ends_with(&self.pattern),
59+
PatternOp::Contains => variable.contains(&self.pattern),
60+
}
61+
}
62+
}
63+
64+
/// Creates a new `Predicate` that ensures a str starts with `pattern`
65+
///
66+
/// # Examples
67+
///
68+
/// ```
69+
/// use predicates::prelude::*;
70+
///
71+
/// let predicate_fn = predicate::str::starts_with("Hello");
72+
/// assert_eq!(true, predicate_fn.eval("Hello World"));
73+
/// assert_eq!(false, predicate_fn.eval("Goodbye World"));
74+
/// ```
75+
pub fn starts_with<P>(pattern: P) -> PatternPredicate
76+
where
77+
P: Into<String>,
78+
{
79+
PatternPredicate {
80+
pattern: pattern.into(),
81+
op: PatternOp::StartsWith,
82+
}
83+
}
84+
85+
/// Creates a new `Predicate` that ensures a str ends with `pattern`
86+
///
87+
/// # Examples
88+
///
89+
/// ```
90+
/// use predicates::prelude::*;
91+
///
92+
/// let predicate_fn = predicate::str::ends_with("World");
93+
/// assert_eq!(true, predicate_fn.eval("Hello World"));
94+
/// assert_eq!(false, predicate_fn.eval("Hello Moon"));
95+
/// ```
96+
pub fn ends_with<P>(pattern: P) -> PatternPredicate
97+
where
98+
P: Into<String>,
99+
{
100+
PatternPredicate {
101+
pattern: pattern.into(),
102+
op: PatternOp::EndsWith,
103+
}
104+
}
105+
106+
/// Creates a new `Predicate` that ensures a str contains `pattern`
107+
///
108+
/// # Examples
109+
///
110+
/// ```
111+
/// use predicates::prelude::*;
112+
///
113+
/// let predicate_fn = predicate::str::contains("Two");
114+
/// assert_eq!(true, predicate_fn.eval("One Two Three"));
115+
/// assert_eq!(false, predicate_fn.eval("Four Five Six"));
116+
/// ```
117+
pub fn contains<P>(pattern: P) -> PatternPredicate
118+
where
119+
P: Into<String>,
120+
{
121+
PatternPredicate {
122+
pattern: pattern.into(),
123+
op: PatternOp::Contains,
124+
}
125+
}

src/str/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
//!
1111
//! This module contains predicates specific to string handling.
1212
13+
mod basics;
14+
pub use self::basics::*;
15+
1316
#[cfg(feature = "difference")]
1417
mod difference;
1518
#[cfg(feature = "difference")]

0 commit comments

Comments
 (0)