Skip to content

Commit 88b72f9

Browse files
committed
fix(predicate): Break out boolean logic from trait
BREAKING CHANGE: `Predicate` trait is changed but most use cases should not be impacted.
1 parent 8471493 commit 88b72f9

File tree

3 files changed

+71
-59
lines changed

3 files changed

+71
-59
lines changed

src/boolean.rs

+70
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,73 @@ where
132132
!self.inner.eval(item)
133133
}
134134
}
135+
136+
/// `Predicate` extension that adds boolean logic.
137+
pub trait PredicateBooleanExt<Item: ?Sized>
138+
where
139+
Self: Predicate<Item>,
140+
{
141+
/// Compute the logical AND of two `Predicate` results, returning the result.
142+
///
143+
/// # Examples
144+
///
145+
/// ```
146+
/// use predicates::prelude::*;
147+
///
148+
/// let predicate_fn1 = predicate::always().and(predicate::always());
149+
/// let predicate_fn2 = predicate::always().and(predicate::never());
150+
/// assert_eq!(true, predicate_fn1.eval(&4));
151+
/// assert_eq!(false, predicate_fn2.eval(&4));
152+
fn and<B>(self, other: B) -> AndPredicate<Self, B, Item>
153+
where
154+
B: Predicate<Item>,
155+
Self: Sized,
156+
{
157+
AndPredicate::new(self, other)
158+
}
159+
160+
/// Compute the logical OR of two `Predicate` results, returning the result.
161+
///
162+
/// # Examples
163+
///
164+
/// ```
165+
/// use predicates::prelude::*;
166+
///
167+
/// let predicate_fn1 = predicate::always().or(predicate::always());
168+
/// let predicate_fn2 = predicate::always().or(predicate::never());
169+
/// let predicate_fn3 = predicate::never().or(predicate::never());
170+
/// assert_eq!(true, predicate_fn1.eval(&4));
171+
/// assert_eq!(true, predicate_fn2.eval(&4));
172+
/// assert_eq!(false, predicate_fn3.eval(&4));
173+
fn or<B>(self, other: B) -> OrPredicate<Self, B, Item>
174+
where
175+
B: Predicate<Item>,
176+
Self: Sized,
177+
{
178+
OrPredicate::new(self, other)
179+
}
180+
181+
/// Compute the logical NOT of a `Predicate`, returning the result.
182+
///
183+
/// # Examples
184+
///
185+
/// ```
186+
/// use predicates::prelude::*;
187+
///
188+
/// let predicate_fn1 = predicate::always().not();
189+
/// let predicate_fn2 = predicate::never().not();
190+
/// assert_eq!(false, predicate_fn1.eval(&4));
191+
/// assert_eq!(true, predicate_fn2.eval(&4));
192+
fn not(self) -> NotPredicate<Self, Item>
193+
where
194+
Self: Sized,
195+
{
196+
NotPredicate::new(self)
197+
}
198+
}
199+
200+
impl<P, Item> PredicateBooleanExt<Item> for P
201+
where
202+
P: Predicate<Item>,
203+
{
204+
}

src/core.rs

-59
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use boolean::{AndPredicate, NotPredicate, OrPredicate};
109
use boxed::BoxPredicate;
1110

1211
/// Trait for generically evaluating a type against a dynamically created
@@ -21,64 +20,6 @@ pub trait Predicate<Item: ?Sized> {
2120
/// boolean.
2221
fn eval(&self, variable: &Item) -> bool;
2322

24-
/// Compute the logical AND of two `Predicate` results, returning the result.
25-
///
26-
/// # Examples
27-
///
28-
/// ```
29-
/// use predicates::prelude::*;
30-
///
31-
/// let predicate_fn1 = predicate::always().and(predicate::always());
32-
/// let predicate_fn2 = predicate::always().and(predicate::never());
33-
/// assert_eq!(true, predicate_fn1.eval(&4));
34-
/// assert_eq!(false, predicate_fn2.eval(&4));
35-
fn and<B>(self, other: B) -> AndPredicate<Self, B, Item>
36-
where
37-
B: Predicate<Item>,
38-
Self: Sized,
39-
{
40-
AndPredicate::new(self, other)
41-
}
42-
43-
/// Compute the logical OR of two `Predicate` results, returning the result.
44-
///
45-
/// # Examples
46-
///
47-
/// ```
48-
/// use predicates::prelude::*;
49-
///
50-
/// let predicate_fn1 = predicate::always().or(predicate::always());
51-
/// let predicate_fn2 = predicate::always().or(predicate::never());
52-
/// let predicate_fn3 = predicate::never().or(predicate::never());
53-
/// assert_eq!(true, predicate_fn1.eval(&4));
54-
/// assert_eq!(true, predicate_fn2.eval(&4));
55-
/// assert_eq!(false, predicate_fn3.eval(&4));
56-
fn or<B>(self, other: B) -> OrPredicate<Self, B, Item>
57-
where
58-
B: Predicate<Item>,
59-
Self: Sized,
60-
{
61-
OrPredicate::new(self, other)
62-
}
63-
64-
/// Compute the logical NOT of a `Predicate`, returning the result.
65-
///
66-
/// # Examples
67-
///
68-
/// ```
69-
/// use predicates::prelude::*;
70-
///
71-
/// let predicate_fn1 = predicate::always().not();
72-
/// let predicate_fn2 = predicate::never().not();
73-
/// assert_eq!(false, predicate_fn1.eval(&4));
74-
/// assert_eq!(true, predicate_fn2.eval(&4));
75-
fn not(self) -> NotPredicate<Self, Item>
76-
where
77-
Self: Sized,
78-
{
79-
NotPredicate::new(self)
80-
}
81-
8223
/// Returns a `BoxPredicate` wrapper around this `Predicate` type.
8324
///
8425
/// Returns a `BoxPredicate` wrapper around this `Predicate type. The

src/prelude.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! Module that contains the essentials for working with predicates.
1010
1111
pub use core::Predicate;
12+
pub use boolean::PredicateBooleanExt;
1213

1314
/// Predicate factories
1415
pub mod predicate {

0 commit comments

Comments
 (0)