pub trait Predicate<T> {
// Required methods
fn test(&self, value: &T) -> bool;
fn into_box(self) -> BoxPredicate<T>
where Self: Sized + 'static,
T: 'static;
fn into_rc(self) -> RcPredicate<T>
where Self: Sized + 'static,
T: 'static;
fn into_arc(self) -> ArcPredicate<T>
where Self: Sized + Send + Sync + 'static,
T: Send + Sync + 'static;
fn into_fn(self) -> impl Fn(&T) -> bool
where Self: Sized + 'static,
T: 'static;
}Expand description
A predicate trait for testing whether a value satisfies a condition.
This trait represents a pure judgment operation - it tests whether a given value meets certain criteria without modifying either the value or the predicate itself (from the user’s perspective). This semantic clarity distinguishes predicates from consumers or transformers.
§Design Rationale
This is a minimal trait that only defines:
- The core
testmethod using&self(immutable borrow) - Type conversion methods (
into_box,into_rc,into_arc) - Closure conversion method (
into_fn)
Logical composition methods (and, or, not) are intentionally
not part of the trait. Instead, they are implemented on concrete
types (BoxPredicate, RcPredicate, ArcPredicate), allowing each
implementation to maintain its specific ownership characteristics:
BoxPredicate: Methods consumeself(single ownership)RcPredicate: Methods borrow&self(shared ownership)ArcPredicate: Methods borrow&self(thread-safe shared ownership)
§Why &self Instead of &mut self?
Predicates use &self because:
- Semantic Clarity: A predicate is a judgment, not a mutation
- Flexibility: Can be used in immutable contexts
- Simplicity: No need for
mutin user code - Interior Mutability: State (if needed) can be managed with
RefCell,Cell, orMutex
§Automatic Implementation for Closures
Any closure matching Fn(&T) -> bool automatically implements this
trait, providing seamless integration with Rust’s closure system.
§Examples
§Basic Usage
use prism3_function::predicate::Predicate;
let is_positive = |x: &i32| *x > 0;
assert!(is_positive.test(&5));
assert!(!is_positive.test(&-3));§Type Conversion
use prism3_function::predicate::{Predicate, BoxPredicate};
let closure = |x: &i32| *x > 0;
let boxed: BoxPredicate<i32> = closure.into_box();
assert!(boxed.test(&5));§Stateful Predicate with Interior Mutability
use prism3_function::predicate::{Predicate, BoxPredicate};
use std::cell::Cell;
let count = Cell::new(0);
let counting_pred = BoxPredicate::new(move |x: &i32| {
count.set(count.get() + 1);
*x > 0
});
// Note: No `mut` needed - interior mutability handles state
assert!(counting_pred.test(&5));
assert!(!counting_pred.test(&-3));§Author
Haixing Hu
Required Methods§
Sourcefn into_box(self) -> BoxPredicate<T>where
Self: Sized + 'static,
T: 'static,
fn into_box(self) -> BoxPredicate<T>where
Self: Sized + 'static,
T: 'static,
Sourcefn into_rc(self) -> RcPredicate<T>where
Self: Sized + 'static,
T: 'static,
fn into_rc(self) -> RcPredicate<T>where
Self: Sized + 'static,
T: 'static,
Sourcefn into_arc(self) -> ArcPredicate<T>
fn into_arc(self) -> ArcPredicate<T>
Sourcefn into_fn(self) -> impl Fn(&T) -> boolwhere
Self: Sized + 'static,
T: 'static,
fn into_fn(self) -> impl Fn(&T) -> boolwhere
Self: Sized + 'static,
T: 'static,
Converts this predicate into a closure that can be used directly with standard library methods.
This method consumes the predicate and returns a closure with
signature Fn(&T) -> bool. Since Fn is a subtrait of FnMut,
the returned closure can be used in any context that requires
either Fn(&T) -> bool or FnMut(&T) -> bool, making it
compatible with methods like Iterator::filter,
Iterator::filter_map, Vec::retain, and similar standard
library APIs.
§Returns
A closure implementing Fn(&T) -> bool (also usable as
FnMut(&T) -> bool).
§Examples
§Using with Iterator::filter (requires FnMut)
use prism3_function::predicate::{Predicate, BoxPredicate};
let pred = BoxPredicate::new(|x: &i32| *x > 0);
let numbers = vec![-2, -1, 0, 1, 2, 3];
let positives: Vec<_> = numbers.iter()
.copied()
.filter(pred.into_fn())
.collect();
assert_eq!(positives, vec![1, 2, 3]);§Using with Vec::retain (requires FnMut)
use prism3_function::predicate::{Predicate, BoxPredicate};
let pred = BoxPredicate::new(|x: &i32| *x % 2 == 0);
let mut numbers = vec![1, 2, 3, 4, 5, 6];
numbers.retain(pred.into_fn());
assert_eq!(numbers, vec![2, 4, 6]);