Skip to content

Commit a3c8d61

Browse files
authored
Merge pull request #35 from epage/specialized
feat(str): Specialized string predicates
2 parents 874b7c3 + e846b95 commit a3c8d61

File tree

5 files changed

+234
-54
lines changed

5 files changed

+234
-54
lines changed

src/set.rs renamed to src/iter.rs

+52-51
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,49 @@ use Predicate;
2020
/// Note that this implementation places the fewest restrictions on the
2121
/// underlying `Item` type at the expense of having the least performant
2222
/// implementation (linear search). If the type to be searched is `Hash + Eq`,
23-
/// it is much more efficient to use `HashableContainsPredicate` and
24-
/// `contains_hashable`. The implementation-specific predicates will be
23+
/// it is much more efficient to use `HashableInPredicate` and
24+
/// `in_hash`. The implementation-specific predicates will be
2525
/// deprecated when Rust supports trait specialization.
2626
#[derive(Debug)]
27-
pub struct ContainsPredicate<T>
27+
pub struct InPredicate<T>
2828
where
2929
T: PartialEq,
3030
{
3131
inner: Vec<T>,
3232
}
3333

34-
impl<T> Predicate<T> for ContainsPredicate<T>
34+
impl<T> InPredicate<T>
35+
where
36+
T: Ord,
37+
{
38+
/// Creates a new predicate that will return `true` when the given `variable` is
39+
/// contained with the set of items provided.
40+
///
41+
/// Note that this implementation requires `Item` to be `Ord`. The
42+
/// `InPredicate` uses a less efficient search algorithm but only
43+
/// requires `Item` implement `PartialEq`. The implementation-specific
44+
/// predicates will be deprecated when Rust supports trait specialization.
45+
///
46+
/// # Examples
47+
///
48+
/// ```
49+
/// use predicates::prelude::*;
50+
///
51+
/// let predicate_fn = predicate::in_iter(vec![1, 3, 5]).sort();
52+
/// assert_eq!(true, predicate_fn.eval(&1));
53+
/// assert_eq!(false, predicate_fn.eval(&2));
54+
/// assert_eq!(true, predicate_fn.eval(&3));
55+
/// assert_eq!(false, predicate_fn.eval(&4));
56+
/// assert_eq!(true, predicate_fn.eval(&5));
57+
/// ```
58+
pub fn sort(self) -> OrdInPredicate<T> {
59+
let mut items = self.inner;
60+
items.sort();
61+
OrdInPredicate { inner: items }
62+
}
63+
}
64+
65+
impl<T> Predicate<T> for InPredicate<T>
3566
where
3667
T: PartialEq,
3768
{
@@ -46,28 +77,28 @@ where
4677
/// Note that this implementation places the fewest restrictions on the
4778
/// underlying `Item` type at the expense of having the least performant
4879
/// implementation (linear search). If the type to be searched is `Hash + Eq`,
49-
/// it is much more efficient to use `HashableContainsPredicate` and
50-
/// `contains_hashable`. The implementation-specific predicates will be
80+
/// it is much more efficient to use `HashableInPredicate` and
81+
/// `in_hash`. The implementation-specific predicates will be
5182
/// deprecated when Rust supports trait specialization.
5283
///
5384
/// # Examples
5485
///
5586
/// ```
5687
/// use predicates::prelude::*;
5788
///
58-
/// let predicate_fn = predicate::contains(vec![1, 3, 5]);
89+
/// let predicate_fn = predicate::in_iter(vec![1, 3, 5]);
5990
/// assert_eq!(true, predicate_fn.eval(&1));
6091
/// assert_eq!(false, predicate_fn.eval(&2));
6192
/// assert_eq!(true, predicate_fn.eval(&3));
6293
/// assert_eq!(false, predicate_fn.eval(&4));
6394
/// assert_eq!(true, predicate_fn.eval(&5));
6495
/// ```
65-
pub fn contains<I, T>(iter: I) -> ContainsPredicate<T>
96+
pub fn in_iter<I, T>(iter: I) -> InPredicate<T>
6697
where
6798
T: PartialEq,
6899
I: IntoIterator<Item = T>,
69100
{
70-
ContainsPredicate {
101+
InPredicate {
71102
inner: Vec::from_iter(iter),
72103
}
73104
}
@@ -76,20 +107,20 @@ where
76107
/// set, otherwise returns `false`.
77108
///
78109
/// Note that this implementation requires `Item` to be `Ord`. The
79-
/// `ContainsPredicate` uses a less efficient search algorithm but only
110+
/// `InPredicate` uses a less efficient search algorithm but only
80111
/// requires `Item` implement `PartialEq`. The implementation-specific
81112
/// predicates will be deprecated when Rust supports trait specialization.
82113
///
83-
/// This is created by the `predicate::contains_ord` function.
114+
/// This is created by the `predicate::in_iter(...).sort` function.
84115
#[derive(Debug)]
85-
pub struct OrdContainsPredicate<T>
116+
pub struct OrdInPredicate<T>
86117
where
87118
T: Ord,
88119
{
89120
inner: Vec<T>,
90121
}
91122

92-
impl<T> Predicate<T> for OrdContainsPredicate<T>
123+
impl<T> Predicate<T> for OrdInPredicate<T>
93124
where
94125
T: Ord,
95126
{
@@ -98,54 +129,24 @@ where
98129
}
99130
}
100131

101-
/// Creates a new predicate that will return `true` when the given `variable` is
102-
/// contained with the set of items provided.
103-
///
104-
/// Note that this implementation requires `Item` to be `Ord`. The
105-
/// `ContainsPredicate` uses a less efficient search algorithm but only
106-
/// requires `Item` implement `PartialEq`. The implementation-specific
107-
/// predicates will be deprecated when Rust supports trait specialization.
108-
///
109-
/// # Examples
110-
///
111-
/// ```
112-
/// use predicates::prelude::*;
113-
///
114-
/// let predicate_fn = predicate::contains_ord(vec![1, 3, 5]);
115-
/// assert_eq!(true, predicate_fn.eval(&1));
116-
/// assert_eq!(false, predicate_fn.eval(&2));
117-
/// assert_eq!(true, predicate_fn.eval(&3));
118-
/// assert_eq!(false, predicate_fn.eval(&4));
119-
/// assert_eq!(true, predicate_fn.eval(&5));
120-
/// ```
121-
pub fn contains_ord<I, T>(iter: I) -> OrdContainsPredicate<T>
122-
where
123-
T: Ord,
124-
I: IntoIterator<Item = T>,
125-
{
126-
let mut items = Vec::from_iter(iter);
127-
items.sort();
128-
OrdContainsPredicate { inner: items }
129-
}
130-
131132
/// Predicate that returns `true` if `variable` is a member of the pre-defined
132133
/// `HashSet`, otherwise returns `false`.
133134
///
134135
/// Note that this implementation requires `Item` to be `Hash + Eq`. The
135-
/// `ContainsPredicate` uses a less efficient search algorithm but only
136+
/// `InPredicate` uses a less efficient search algorithm but only
136137
/// requires `Item` implement `PartialEq`. The implementation-specific
137138
/// predicates will be deprecated when Rust supports trait specialization.
138139
///
139-
/// This is created by the `predicate::contains_hashable` function.
140+
/// This is created by the `predicate::in_hash` function.
140141
#[derive(Debug)]
141-
pub struct HashableContainsPredicate<T>
142+
pub struct HashableInPredicate<T>
142143
where
143144
T: Hash + Eq,
144145
{
145146
inner: HashSet<T>,
146147
}
147148

148-
impl<T> Predicate<T> for HashableContainsPredicate<T>
149+
impl<T> Predicate<T> for HashableInPredicate<T>
149150
where
150151
T: Hash + Eq,
151152
{
@@ -158,7 +159,7 @@ where
158159
/// contained with the set of items provided.
159160
///
160161
/// Note that this implementation requires `Item` to be `Hash + Eq`. The
161-
/// `ContainsPredicate` uses a less efficient search algorithm but only
162+
/// `InPredicate` uses a less efficient search algorithm but only
162163
/// requires `Item` implement `PartialEq`. The implementation-specific
163164
/// predicates will be deprecated when Rust supports trait specialization.
164165
///
@@ -167,19 +168,19 @@ where
167168
/// ```
168169
/// use predicates::prelude::*;
169170
///
170-
/// let predicate_fn = predicate::contains_hashable(vec![1, 3, 5]);
171+
/// let predicate_fn = predicate::in_hash(vec![1, 3, 5]);
171172
/// assert_eq!(true, predicate_fn.eval(&1));
172173
/// assert_eq!(false, predicate_fn.eval(&2));
173174
/// assert_eq!(true, predicate_fn.eval(&3));
174175
/// assert_eq!(false, predicate_fn.eval(&4));
175176
/// assert_eq!(true, predicate_fn.eval(&5));
176177
/// ```
177-
pub fn contains_hashable<I, T>(iter: I) -> HashableContainsPredicate<T>
178+
pub fn in_hash<I, T>(iter: I) -> HashableInPredicate<T>
178179
where
179180
T: Hash + Eq,
180181
I: IntoIterator<Item = T>,
181182
{
182-
HashableContainsPredicate {
183+
HashableInPredicate {
183184
inner: HashSet::from_iter(iter),
184185
}
185186
}

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
//! }
7070
//!
7171
//! assert_eq!(true, IsTheAnswer.eval(&42));
72-
//! let almost_the_answer = IsTheAnswer.or(predicate::contains(vec![41, 43]));
72+
//! let almost_the_answer = IsTheAnswer.or(predicate::in_iter(vec![41, 43]));
7373
//! assert_eq!(true, almost_the_answer.eval(&41));
7474
//!
7575
//! // Any function over a reference to the desired `Item` that returns `bool`
@@ -102,7 +102,7 @@ pub use boxed::BoxPredicate;
102102
pub mod constant;
103103
pub mod function;
104104
pub mod ord;
105-
pub mod set;
105+
pub mod iter;
106106

107107
// combinators
108108
pub mod boolean;

src/prelude.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ pub mod predicate {
1616
pub use constant::{always, never};
1717
pub use function::function;
1818
pub use ord::{eq, ge, gt, le, lt, ne};
19-
pub use set::{contains, contains_hashable, contains_ord};
19+
pub use iter::{in_hash, in_iter};
2020

2121
/// `str` Predicate factories
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

0 commit comments

Comments
 (0)