Module bi_predicate

Module bi_predicate 

Source
Expand description

§BiPredicate Abstraction

Provides a Rust implementation similar to Java’s BiPredicate interface for testing whether two values satisfy a condition.

§Core Semantics

A BiPredicate is fundamentally a pure judgment operation that tests whether two values satisfy a specific condition. It should be:

  • Read-only: Does not modify the tested values
  • Side-effect free: Does not change external state (from the user’s perspective)
  • Repeatable: Same inputs should produce the same result
  • Deterministic: Judgment logic should be predictable

§Design Philosophy

This module follows the same principles as the Predicate module:

  1. Single Trait: Only one BiPredicate<T, U> trait with &self, keeping the API simple and semantically clear
  2. No BiPredicateMut: All stateful scenarios use interior mutability (RefCell, Cell, Mutex) instead of &mut self
  3. No BiPredicateOnce: Violates bi-predicate semantics - judgments should be repeatable
  4. Three Implementations: BoxBiPredicate, RcBiPredicate, and ArcBiPredicate cover all ownership scenarios

§Type Selection Guide

ScenarioRecommended TypeReason
One-time useBoxBiPredicateSingle ownership, no overhead
Multi-threadedArcBiPredicateThread-safe, clonable
Single-threaded reuseRcBiPredicateBetter performance
Stateful predicateAny type + RefCell/Cell/MutexInterior mutability

§Examples

§Basic Usage with Closures

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(&-3, &-7));

§BoxBiPredicate - Single Ownership

use prism3_function::bi_predicate::{BiPredicate, BoxBiPredicate};

let pred = BoxBiPredicate::new(|x: &i32, y: &i32| x + y > 0)
    .and(BoxBiPredicate::new(|x, y| x > y));
assert!(pred.test(&10, &5));

§Closure Composition with Extension Methods

Closures automatically gain and, or, not methods through the FnBiPredicateOps extension trait, returning BoxBiPredicate:

use prism3_function::bi_predicate::{BiPredicate,
    FnBiPredicateOps};

// Compose closures directly - result is BoxBiPredicate
let is_sum_positive = |x: &i32, y: &i32| x + y > 0;
let first_larger = |x: &i32, y: &i32| x > y;

let combined = is_sum_positive.and(first_larger);
assert!(combined.test(&10, &5));
assert!(!combined.test(&3, &8));

// Use `or` for disjunction
let negative_sum = |x: &i32, y: &i32| x + y < 0;
let both_large = |x: &i32, y: &i32| *x > 100 && *y > 100;
let either = negative_sum.or(both_large);
assert!(either.test(&-10, &5));
assert!(either.test(&200, &150));

§RcBiPredicate - Single-threaded Reuse

use prism3_function::bi_predicate::{BiPredicate, RcBiPredicate};

let pred = RcBiPredicate::new(|x: &i32, y: &i32| x + y > 0);
let combined1 = pred.and(RcBiPredicate::new(|x, y| x > y));
let combined2 = pred.or(RcBiPredicate::new(|x, y| *x > 100));

// Original predicate is still usable
assert!(pred.test(&5, &3));

§ArcBiPredicate - Thread-safe Sharing

use prism3_function::bi_predicate::{BiPredicate, ArcBiPredicate};
use std::thread;

let pred = ArcBiPredicate::new(|x: &i32, y: &i32| x + y > 0);
let pred_clone = pred.clone();

let handle = thread::spawn(move || {
    pred_clone.test(&10, &5)
});

assert!(handle.join().unwrap());
assert!(pred.test(&3, &7));  // Original still usable

§Stateful BiPredicates with Interior Mutability

use prism3_function::bi_predicate::{BiPredicate, BoxBiPredicate};
use std::cell::Cell;

let count = Cell::new(0);
let pred = BoxBiPredicate::new(move |x: &i32, y: &i32| {
    count.set(count.get() + 1);
    x + y > 0
});

// No need for `mut` - interior mutability handles state
assert!(pred.test(&5, &3));
assert!(!pred.test(&-8, &-3));

§Author

Haixing Hu

Structs§

ArcBiPredicate
An Arc-based bi-predicate with thread-safe shared ownership.
BoxBiPredicate
A Box-based bi-predicate with single ownership.
RcBiPredicate
An Rc-based bi-predicate with single-threaded shared ownership.

Traits§

BiPredicate
A bi-predicate trait for testing whether two values satisfy a condition.
FnBiPredicateOps
Extension trait providing logical composition methods for closures.