Skip to main content

qubit_function/predicates/
predicate.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Predicate Abstraction
10//!
11//! Provides a Rust implementation similar to Java's `Predicate` interface
12//! for condition testing and logical composition.
13//!
14//! ## Core Semantics
15//!
16//! A **Predicate** is fundamentally a pure judgment operation that tests
17//! whether a value satisfies a specific condition. It should be:
18//!
19//! - **Read-only**: Does not modify the tested value
20//! - **Side-effect free**: Does not change external state (from the user's
21//!   perspective)
22//! - **Repeatable**: Same input should produce the same result
23//! - **Deterministic**: Judgment logic should be predictable
24//!
25//! It is similar to the `Fn(&T) -> bool` trait in the standard library.
26//!
27//! ## Design Philosophy
28//!
29//! This module follows these principles:
30//!
31//! 1. **Single Trait**: Only one `Predicate<T>` trait with `&self`, keeping
32//!    the API simple and semantically clear
33//! 2. **No PredicateMut**: All stateful scenarios use interior mutability
34//!    (`RefCell`, `Cell`, `Mutex`) instead of `&mut self`
35//! 3. **No PredicateOnce**: Violates predicate semantics - judgments should
36//!    be repeatable
37//! 4. **Three Implementations**: `BoxPredicate`, `RcPredicate`, and
38//!    `ArcPredicate` cover all ownership scenarios
39//!
40//! ## Type Selection Guide
41//!
42//! | Scenario | Recommended Type | Reason |
43//! |----------|------------------|--------|
44//! | One-time use | `BoxPredicate` | Single ownership, no overhead |
45//! | Multi-threaded | `ArcPredicate` | Thread-safe, clonable |
46//! | Single-threaded reuse | `RcPredicate` | Better performance |
47//! | Stateful predicate | Any type + `RefCell`/`Cell`/`Mutex` | Interior mutability |
48//!
49//! ## Examples
50//!
51//! ### Basic Usage with Closures
52//!
53//! ```rust
54//! use qubit_function::Predicate;
55//!
56//! let is_positive = |x: &i32| *x > 0;
57//! assert!(is_positive.test(&5));
58//! assert!(!is_positive.test(&-3));
59//! ```
60//!
61//! ### BoxPredicate - Single Ownership
62//!
63//! ```rust
64//! use qubit_function::{Predicate, BoxPredicate};
65//!
66//! let pred = BoxPredicate::new(|x: &i32| *x > 0)
67//!     .and(BoxPredicate::new(|x| x % 2 == 0));
68//! assert!(pred.test(&4));
69//! ```
70//!
71//! ### Closure Composition with Extension Methods
72//!
73//! Closures automatically gain `and`, `or`, `not` methods through the
74//! `FnPredicateOps` extension trait, returning `BoxPredicate`:
75//!
76//! ```rust
77//! use qubit_function::{Predicate, FnPredicateOps, BoxPredicate};
78//!
79//! // Compose closures directly - result is BoxPredicate
80//! let is_positive = |x: &i32| *x > 0;
81//! let is_even = |x: &i32| x % 2 == 0;
82//!
83//! let positive_and_even = is_positive.and(is_even);
84//! assert!(positive_and_even.test(&4));
85//! assert!(!positive_and_even.test(&3));
86//!
87//! // Can chain multiple operations
88//! let pred = (|x: &i32| *x > 0)
89//!     .and(|x: &i32| x % 2 == 0)
90//!     .and(BoxPredicate::new(|x: &i32| *x < 100));
91//! assert!(pred.test(&42));
92//!
93//! // Use `or` for disjunction
94//! let negative_or_large = (|x: &i32| *x < 0)
95//!     .or(|x: &i32| *x > 100);
96//! assert!(negative_or_large.test(&-5));
97//! assert!(negative_or_large.test(&200));
98//!
99//! // Use `not` for negation
100//! let not_zero = (|x: &i32| *x == 0).not();
101//! assert!(not_zero.test(&5));
102//! assert!(!not_zero.test(&0));
103//! ```
104//!
105//! ### Complex Predicate Composition
106//!
107//! Build complex predicates by mixing closures and predicate types:
108//!
109//! ```rust
110//! use qubit_function::{Predicate, BoxPredicate, FnPredicateOps};
111//!
112//! // Start with a closure, compose with BoxPredicate
113//! let in_range = (|x: &i32| *x >= 0)
114//!     .and(BoxPredicate::new(|x| *x <= 100));
115//!
116//! // Use in filtering
117//! let numbers = vec![-10, 5, 50, 150, 75];
118//! let filtered: Vec<_> = numbers.iter()
119//!     .copied()
120//!     .filter(in_range.into_fn())
121//!     .collect();
122//! assert_eq!(filtered, vec![5, 50, 75]);
123//! ```
124//!
125//! ### RcPredicate - Single-threaded Reuse
126//!
127//! ```rust
128//! use qubit_function::{Predicate, RcPredicate};
129//!
130//! let pred = RcPredicate::new(|x: &i32| *x > 0);
131//! let combined1 = pred.and(RcPredicate::new(|x| x % 2 == 0));
132//! let combined2 = pred.or(RcPredicate::new(|x| *x > 100));
133//!
134//! // Original predicate is still usable
135//! assert!(pred.test(&5));
136//! ```
137//!
138//! ### ArcPredicate - Thread-safe Sharing
139//!
140//! ```rust
141//! use qubit_function::{Predicate, ArcPredicate};
142//! use std::thread;
143//!
144//! let pred = ArcPredicate::new(|x: &i32| *x > 0);
145//! let pred_clone = pred.clone();
146//!
147//! let handle = thread::spawn(move || {
148//!     pred_clone.test(&10)
149//! });
150//!
151//! assert!(handle.join().unwrap());
152//! assert!(pred.test(&5));  // Original still usable
153//! ```
154//!
155//! ### Stateful Predicates with Interior Mutability
156//!
157//! ```rust
158//! use qubit_function::{Predicate, BoxPredicate};
159//! use std::cell::Cell;
160//!
161//! let count = Cell::new(0);
162//! let pred = BoxPredicate::new(move |x: &i32| {
163//!     count.set(count.get() + 1);
164//!     *x > 0
165//! });
166//!
167//! // No need for `mut` - interior mutability handles state
168//! assert!(pred.test(&5));
169//! assert!(!pred.test(&-3));
170//! ```
171//!
172//! ## Author
173//!
174//! Haixing Hu
175use std::rc::Rc;
176use std::sync::Arc;
177
178use crate::macros::{
179    impl_arc_conversions,
180    impl_box_conversions,
181    impl_closure_trait,
182    impl_rc_conversions,
183};
184use crate::predicates::macros::{
185    constants::{
186        ALWAYS_FALSE_NAME,
187        ALWAYS_TRUE_NAME,
188    },
189    impl_box_predicate_methods,
190    impl_predicate_clone,
191    impl_predicate_common_methods,
192    impl_predicate_debug_display,
193    impl_shared_predicate_methods,
194};
195
196mod box_predicate;
197pub use box_predicate::BoxPredicate;
198mod rc_predicate;
199pub use rc_predicate::RcPredicate;
200mod arc_predicate;
201pub use arc_predicate::ArcPredicate;
202mod fn_predicate_ops;
203pub use fn_predicate_ops::FnPredicateOps;
204
205/// A predicate trait for testing whether a value satisfies a condition.
206///
207/// This trait represents a **pure judgment operation** - it tests whether
208/// a given value meets certain criteria without modifying either the value
209/// or the predicate itself (from the user's perspective). This semantic
210/// clarity distinguishes predicates from consumers or transformers.
211///
212/// ## Design Rationale
213///
214/// This is a **minimal trait** that only defines:
215/// - The core `test` method using `&self` (immutable borrow)
216/// - Type conversion methods (`into_box`, `into_rc`, `into_arc`)
217/// - Closure conversion method (`into_fn`)
218///
219/// Logical composition methods (`and`, `or`, `not`) are intentionally
220/// **not** part of the trait. Instead, they are implemented on concrete
221/// types (`BoxPredicate`, `RcPredicate`, `ArcPredicate`), allowing each
222/// implementation to maintain its specific ownership characteristics:
223///
224/// - `BoxPredicate`: Methods consume `self` (single ownership)
225/// - `RcPredicate`: Methods borrow `&self` (shared ownership)
226/// - `ArcPredicate`: Methods borrow `&self` (thread-safe shared ownership)
227///
228/// ## Why `&self` Instead of `&mut self`?
229///
230/// Predicates use `&self` because:
231///
232/// 1. **Semantic Clarity**: A predicate is a judgment, not a mutation
233/// 2. **Flexibility**: Can be used in immutable contexts
234/// 3. **Simplicity**: No need for `mut` in user code
235/// 4. **Interior Mutability**: State (if needed) can be managed with
236///    `RefCell`, `Cell`, or `Mutex`
237///
238/// ## Automatic Implementation for Closures
239///
240/// Any closure matching `Fn(&T) -> bool` automatically implements this
241/// trait, providing seamless integration with Rust's closure system.
242///
243/// ## Examples
244///
245/// ### Basic Usage
246///
247/// ```rust
248/// use qubit_function::Predicate;
249///
250/// let is_positive = |x: &i32| *x > 0;
251/// assert!(is_positive.test(&5));
252/// assert!(!is_positive.test(&-3));
253/// ```
254///
255/// ### Type Conversion
256///
257/// ```rust
258/// use qubit_function::{Predicate, BoxPredicate};
259///
260/// let closure = |x: &i32| *x > 0;
261/// let boxed: BoxPredicate<i32> = closure.into_box();
262/// assert!(boxed.test(&5));
263/// ```
264///
265/// ### Stateful Predicate with Interior Mutability
266///
267/// ```rust
268/// use qubit_function::{Predicate, BoxPredicate};
269/// use std::cell::Cell;
270///
271/// let count = Cell::new(0);
272/// let counting_pred = BoxPredicate::new(move |x: &i32| {
273///     count.set(count.get() + 1);
274///     *x > 0
275/// });
276///
277/// // Note: No `mut` needed - interior mutability handles state
278/// assert!(counting_pred.test(&5));
279/// assert!(!counting_pred.test(&-3));
280/// ```
281///
282/// ## Author
283///
284/// Haixing Hu
285pub trait Predicate<T> {
286    /// Tests whether the given value satisfies this predicate.
287    ///
288    /// # Parameters
289    ///
290    /// * `value` - The value to test.
291    ///
292    /// # Returns
293    ///
294    /// `true` if the value satisfies this predicate, `false` otherwise.
295    fn test(&self, value: &T) -> bool;
296
297    /// Converts this predicate into a `BoxPredicate`.
298    ///
299    /// The default implementation wraps the predicate in a closure that
300    /// calls the `test` method. Concrete types may override this with
301    /// more efficient implementations.
302    ///
303    /// # Returns
304    ///
305    /// A `BoxPredicate` wrapping this predicate.
306    fn into_box(self) -> BoxPredicate<T>
307    where
308        Self: Sized + 'static,
309    {
310        BoxPredicate::new(move |value: &T| self.test(value))
311    }
312
313    /// Converts this predicate into an `RcPredicate`.
314    ///
315    /// The default implementation wraps the predicate in a closure that
316    /// calls the `test` method. Concrete types may override this with
317    /// more efficient implementations.
318    ///
319    /// # Returns
320    ///
321    /// An `RcPredicate` wrapping this predicate.
322    fn into_rc(self) -> RcPredicate<T>
323    where
324        Self: Sized + 'static,
325    {
326        RcPredicate::new(move |value: &T| self.test(value))
327    }
328
329    /// Converts this predicate into an `ArcPredicate`.
330    ///
331    /// The default implementation wraps the predicate in a closure that
332    /// calls the `test` method. Concrete types may override this with
333    /// more efficient implementations.
334    ///
335    /// # Returns
336    ///
337    /// An `ArcPredicate` wrapping this predicate.
338    fn into_arc(self) -> ArcPredicate<T>
339    where
340        Self: Sized + Send + Sync + 'static,
341    {
342        ArcPredicate::new(move |value: &T| self.test(value))
343    }
344
345    /// Converts this predicate into a closure that can be used directly
346    /// with standard library methods.
347    ///
348    /// This method consumes the predicate and returns a closure with
349    /// signature `Fn(&T) -> bool`. Since `Fn` is a subtrait of `FnMut`,
350    /// the returned closure can be used in any context that requires
351    /// either `Fn(&T) -> bool` or `FnMut(&T) -> bool`, making it
352    /// compatible with methods like `Iterator::filter`,
353    /// `Iterator::filter_map`, `Vec::retain`, and similar standard
354    /// library APIs.
355    ///
356    /// The default implementation returns a closure that calls the
357    /// `test` method. Concrete types may override this with more
358    /// efficient implementations.
359    ///
360    /// # Returns
361    ///
362    /// A closure implementing `Fn(&T) -> bool` (also usable as
363    /// `FnMut(&T) -> bool`).
364    ///
365    /// # Examples
366    ///
367    /// ## Using with `Iterator::filter` (requires `FnMut`)
368    ///
369    /// ```rust
370    /// use qubit_function::{Predicate, BoxPredicate};
371    ///
372    /// let pred = BoxPredicate::new(|x: &i32| *x > 0);
373    ///
374    /// let numbers = vec![-2, -1, 0, 1, 2, 3];
375    /// let positives: Vec<_> = numbers.iter()
376    ///     .copied()
377    ///     .filter(pred.into_fn())
378    ///     .collect();
379    /// assert_eq!(positives, vec![1, 2, 3]);
380    /// ```
381    ///
382    /// ## Using with `Vec::retain` (requires `FnMut`)
383    ///
384    /// ```rust
385    /// use qubit_function::{Predicate, BoxPredicate};
386    ///
387    /// let pred = BoxPredicate::new(|x: &i32| *x % 2 == 0);
388    /// let mut numbers = vec![1, 2, 3, 4, 5, 6];
389    /// numbers.retain(pred.into_fn());
390    /// assert_eq!(numbers, vec![2, 4, 6]);
391    /// ```
392    fn into_fn(self) -> impl Fn(&T) -> bool
393    where
394        Self: Sized + 'static,
395    {
396        move |value: &T| self.test(value)
397    }
398
399    /// Converts a reference to this predicate into a `BoxPredicate`.
400    ///
401    /// This method clones the predicate and then converts it to a
402    /// `BoxPredicate`. The original predicate remains usable after this call.
403    ///
404    /// # Returns
405    ///
406    /// A `BoxPredicate` wrapping a clone of this predicate.
407    fn to_box(&self) -> BoxPredicate<T>
408    where
409        Self: Clone + Sized + 'static,
410    {
411        self.clone().into_box()
412    }
413
414    /// Converts a reference to this predicate into an `RcPredicate`.
415    ///
416    /// This method clones the predicate and then converts it to an
417    /// `RcPredicate`. The original predicate remains usable after this call.
418    ///
419    /// # Returns
420    ///
421    /// An `RcPredicate` wrapping a clone of this predicate.
422    fn to_rc(&self) -> RcPredicate<T>
423    where
424        Self: Clone + Sized + 'static,
425    {
426        self.clone().into_rc()
427    }
428
429    /// Converts a reference to this predicate into an `ArcPredicate`.
430    ///
431    /// This method clones the predicate and then converts it to an
432    /// `ArcPredicate`. The original predicate remains usable after this call.
433    ///
434    /// # Returns
435    ///
436    /// An `ArcPredicate` wrapping a clone of this predicate.
437    fn to_arc(&self) -> ArcPredicate<T>
438    where
439        Self: Clone + Sized + Send + Sync + 'static,
440    {
441        self.clone().into_arc()
442    }
443
444    /// Converts a reference to this predicate into a closure that can be
445    /// used directly with standard library methods.
446    ///
447    /// This method clones the predicate and then converts it to a closure.
448    /// The original predicate remains usable after this call.
449    ///
450    /// The returned closure has signature `Fn(&T) -> bool`. Since `Fn` is a
451    /// subtrait of `FnMut`, it can be used in any context that requires
452    /// either `Fn(&T) -> bool` or `FnMut(&T) -> bool`, making it compatible
453    /// with methods like `Iterator::filter`, `Iterator::filter_map`,
454    /// `Vec::retain`, and similar standard library APIs.
455    ///
456    /// # Returns
457    ///
458    /// A closure implementing `Fn(&T) -> bool` (also usable as
459    /// `FnMut(&T) -> bool`).
460    fn to_fn(&self) -> impl Fn(&T) -> bool
461    where
462        Self: Clone + Sized + 'static,
463    {
464        self.clone().into_fn()
465    }
466}