pub trait BiPredicate<T, U> {
// Required methods
fn test(&self, first: &T, second: &U) -> bool;
fn into_box(self) -> BoxBiPredicate<T, U>
where Self: Sized + 'static,
T: 'static,
U: 'static;
fn into_rc(self) -> RcBiPredicate<T, U>
where Self: Sized + 'static,
T: 'static,
U: 'static;
fn into_arc(self) -> ArcBiPredicate<T, U>
where Self: Sized + Send + Sync + 'static,
T: Send + Sync + 'static,
U: Send + Sync + 'static;
fn into_fn(self) -> impl Fn(&T, &U) -> bool
where Self: Sized + 'static,
T: 'static,
U: 'static;
}Expand description
A bi-predicate trait for testing whether two values satisfy a condition.
This trait represents a pure judgment operation - it tests whether two given values meet certain criteria without modifying either the values or the bi-predicate itself (from the user’s perspective). This semantic clarity distinguishes bi-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, xor, nand,
nor) are intentionally not part of the trait. Instead, they
are implemented on concrete types (BoxBiPredicate,
RcBiPredicate, ArcBiPredicate), allowing each implementation
to maintain its specific ownership characteristics:
BoxBiPredicate: Methods consumeself(single ownership)RcBiPredicate: Methods borrow&self(shared ownership)ArcBiPredicate: Methods borrow&self(thread-safe shared ownership)
§Why &self Instead of &mut self?
Bi-predicates use &self because:
- Semantic Clarity: A bi-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, &U) -> bool automatically implements
this trait, providing seamless integration with Rust’s closure
system.
§Examples
§Basic Usage
use prism3_function::bi_predicate::BiPredicate;
let is_sum_positive = |x: &i32, y: &i32| x + y > 0;
assert!(is_sum_positive.test(&5, &3));
assert!(!is_sum_positive.test(&-5, &-3));§Type Conversion
use prism3_function::bi_predicate::{BiPredicate,
BoxBiPredicate};
let closure = |x: &i32, y: &i32| x + y > 0;
let boxed: BoxBiPredicate<i32, i32> = closure.into_box();
assert!(boxed.test(&5, &3));§Stateful BiPredicate with Interior Mutability
use prism3_function::bi_predicate::{BiPredicate,
BoxBiPredicate};
use std::cell::Cell;
let count = Cell::new(0);
let counting_pred = BoxBiPredicate::new(move |x: &i32, y: &i32| {
count.set(count.get() + 1);
x + y > 0
});
// Note: No `mut` needed - interior mutability handles state
assert!(counting_pred.test(&5, &3));
assert!(!counting_pred.test(&-5, &-3));§Author
Haixing Hu
Required Methods§
Sourcefn into_box(self) -> BoxBiPredicate<T, U>where
Self: Sized + 'static,
T: 'static,
U: 'static,
fn into_box(self) -> BoxBiPredicate<T, U>where
Self: Sized + 'static,
T: 'static,
U: 'static,
Converts this bi-predicate into a BoxBiPredicate.
§Returns
A BoxBiPredicate wrapping this bi-predicate.
Sourcefn into_rc(self) -> RcBiPredicate<T, U>where
Self: Sized + 'static,
T: 'static,
U: 'static,
fn into_rc(self) -> RcBiPredicate<T, U>where
Self: Sized + 'static,
T: 'static,
U: 'static,
Converts this bi-predicate into an RcBiPredicate.
§Returns
An RcBiPredicate wrapping this bi-predicate.
Sourcefn into_arc(self) -> ArcBiPredicate<T, U>
fn into_arc(self) -> ArcBiPredicate<T, U>
Converts this bi-predicate into an ArcBiPredicate.
§Returns
An ArcBiPredicate wrapping this bi-predicate.
Sourcefn into_fn(self) -> impl Fn(&T, &U) -> boolwhere
Self: Sized + 'static,
T: 'static,
U: 'static,
fn into_fn(self) -> impl Fn(&T, &U) -> boolwhere
Self: Sized + 'static,
T: 'static,
U: 'static,
Converts this bi-predicate into a closure that can be used directly with standard library methods.
This method consumes the bi-predicate and returns a closure
with signature Fn(&T, &U) -> bool. Since Fn is a subtrait
of FnMut, the returned closure can be used in any context
that requires either Fn(&T, &U) -> bool or
FnMut(&T, &U) -> bool.
§Returns
A closure implementing Fn(&T, &U) -> bool (also usable as
FnMut(&T, &U) -> bool).
§Examples
§Using with Iterator Methods
use prism3_function::bi_predicate::{BiPredicate,
BoxBiPredicate};
let pred = BoxBiPredicate::new(|x: &i32, y: &i32| x + y > 0);
let pairs = vec![(1, 2), (-1, 3), (5, -6)];
let mut closure = pred.into_fn();
let positives: Vec<_> = pairs.iter()
.filter(|(x, y)| closure(x, y))
.collect();
assert_eq!(positives, vec![&(1, 2), &(-1, 3)]);