Skip to main content

qubit_function/predicates/
predicate.rs

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