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. **Dedicated Stateful API**: Use
35//!    [`StatefulPredicate`](crate::StatefulPredicate) for `FnMut(&T) -> bool`
36//!    closures that need `&mut self`
37//! 3. **No PredicateOnce**: Violates predicate semantics - judgments should
38//!    be repeatable
39//! 4. **Three Implementations**: `BoxPredicate`, `RcPredicate`, and
40//!    `ArcPredicate` cover all ownership scenarios
41//!
42//! ## Type Selection Guide
43//!
44//! | Scenario | Recommended Type | Reason |
45//! |----------|------------------|--------|
46//! | One-time use | `BoxPredicate` | Single ownership, no overhead |
47//! | Multi-threaded | `ArcPredicate` | Thread-safe, clonable |
48//! | Single-threaded reuse | `RcPredicate` | Better performance |
49//! | Stateful closure | `BoxStatefulPredicate`, `RcStatefulPredicate`, or `ArcStatefulPredicate` | Native `FnMut(&T) -> bool` support |
50//! | Immutable API with state | Any `Predicate` type + `RefCell`/`Cell`/`Mutex` | Preserve `Predicate`'s `&self` API |
51//!
52//! ## Examples
53//!
54//! ### Basic Usage with Closures
55//!
56//! ```rust
57//! use qubit_function::Predicate;
58//!
59//! let is_positive = |x: &i32| *x > 0;
60//! assert!(is_positive.test(&5));
61//! assert!(!is_positive.test(&-3));
62//! ```
63//!
64//! ### BoxPredicate - Single Ownership
65//!
66//! ```rust
67//! use qubit_function::{Predicate, BoxPredicate};
68//!
69//! let pred = BoxPredicate::new(|x: &i32| *x > 0)
70//!     .and(BoxPredicate::new(|x| x % 2 == 0));
71//! assert!(pred.test(&4));
72//! ```
73//!
74//! ### Closure Composition with Extension Methods
75//!
76//! Closures automatically gain `and`, `or`, `not` methods through the
77//! `FnPredicateOps` extension trait, returning `BoxPredicate`:
78//!
79//! ```rust
80//! use qubit_function::{Predicate, FnPredicateOps, BoxPredicate};
81//!
82//! // Compose closures directly - result is BoxPredicate
83//! let is_positive = |x: &i32| *x > 0;
84//! let is_even = |x: &i32| x % 2 == 0;
85//!
86//! let positive_and_even = is_positive.and(is_even);
87//! assert!(positive_and_even.test(&4));
88//! assert!(!positive_and_even.test(&3));
89//!
90//! // Can chain multiple operations
91//! let pred = (|x: &i32| *x > 0)
92//!     .and(|x: &i32| x % 2 == 0)
93//!     .and(BoxPredicate::new(|x: &i32| *x < 100));
94//! assert!(pred.test(&42));
95//!
96//! // Use `or` for disjunction
97//! let negative_or_large = (|x: &i32| *x < 0)
98//!     .or(|x: &i32| *x > 100);
99//! assert!(negative_or_large.test(&-5));
100//! assert!(negative_or_large.test(&200));
101//!
102//! // Use `not` for negation
103//! let not_zero = (|x: &i32| *x == 0).not();
104//! assert!(not_zero.test(&5));
105//! assert!(!not_zero.test(&0));
106//! ```
107//!
108//! ### Complex Predicate Composition
109//!
110//! Build complex predicates by mixing closures and predicate types:
111//!
112//! ```rust
113//! use qubit_function::{Predicate, BoxPredicate, FnPredicateOps};
114//!
115//! // Start with a closure, compose with BoxPredicate
116//! let in_range = (|x: &i32| *x >= 0)
117//!     .and(BoxPredicate::new(|x| *x <= 100));
118//!
119//! // Use in filtering
120//! let numbers = vec![-10, 5, 50, 150, 75];
121//! let filtered: Vec<_> = numbers.iter()
122//!     .copied()
123//!     .filter(in_range.into_fn())
124//!     .collect();
125//! assert_eq!(filtered, vec![5, 50, 75]);
126//! ```
127//!
128//! ### RcPredicate - Single-threaded Reuse
129//!
130//! ```rust
131//! use qubit_function::{Predicate, RcPredicate};
132//!
133//! let pred = RcPredicate::new(|x: &i32| *x > 0);
134//! let combined1 = pred.and(RcPredicate::new(|x| x % 2 == 0));
135//! let combined2 = pred.or(RcPredicate::new(|x| *x > 100));
136//!
137//! // Original predicate is still usable
138//! assert!(pred.test(&5));
139//! ```
140//!
141//! ### ArcPredicate - Thread-safe Sharing
142//!
143//! ```rust
144//! use qubit_function::{Predicate, ArcPredicate};
145//! use std::thread;
146//!
147//! let pred = ArcPredicate::new(|x: &i32| *x > 0);
148//! let pred_clone = pred.clone();
149//!
150//! let handle = thread::spawn(move || {
151//!     pred_clone.test(&10)
152//! });
153//!
154//! assert!(handle.join().expect("thread should not panic"));
155//! assert!(pred.test(&5));  // Original still usable
156//! ```
157//!
158//! ### Stateful Predicate Closures
159//!
160//! ```rust
161//! use qubit_function::{StatefulPredicate, BoxStatefulPredicate};
162//!
163//! let mut count = 0;
164//! let mut pred = BoxStatefulPredicate::new(move |x: &i32| {
165//!     count += 1;
166//!     *x > 0
167//! });
168//!
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. **Explicit Stateful Alternative**: Use
234///    [`StatefulPredicate`](crate::StatefulPredicate) when the predicate
235///    closure needs native `FnMut(&T) -> bool` semantics
236///
237/// ## Automatic Implementation for Closures
238///
239/// Any closure matching `Fn(&T) -> bool` automatically implements this
240/// trait, providing seamless integration with Rust's closure system.
241///
242/// ## Examples
243///
244/// ### Basic Usage
245///
246/// ```rust
247/// use qubit_function::Predicate;
248///
249/// let is_positive = |x: &i32| *x > 0;
250/// assert!(is_positive.test(&5));
251/// assert!(!is_positive.test(&-3));
252/// ```
253///
254/// ### Type Conversion
255///
256/// ```rust
257/// use qubit_function::{Predicate, BoxPredicate};
258///
259/// let closure = |x: &i32| *x > 0;
260/// let boxed: BoxPredicate<i32> = closure.into_box();
261/// assert!(boxed.test(&5));
262/// ```
263///
264/// ### Stateful Predicate Alternative
265///
266/// ```rust
267/// use qubit_function::{StatefulPredicate, BoxStatefulPredicate};
268///
269/// let mut count = 0;
270/// let mut counting_pred = BoxStatefulPredicate::new(move |x: &i32| {
271///     count += 1;
272///     *x > 0
273/// });
274///
275/// assert!(counting_pred.test(&5));
276/// assert!(!counting_pred.test(&-3));
277/// ```
278///
279pub trait Predicate<T> {
280    /// Tests whether the given value satisfies this predicate.
281    ///
282    /// # Parameters
283    ///
284    /// * `value` - The value to test.
285    ///
286    /// # Returns
287    ///
288    /// `true` if the value satisfies this predicate, `false` otherwise.
289    fn test(&self, value: &T) -> bool;
290
291    /// Converts this predicate into a `BoxPredicate`.
292    ///
293    /// The default implementation wraps the predicate in a closure that
294    /// calls the `test` method. Concrete types may override this with
295    /// more efficient implementations.
296    ///
297    /// # Returns
298    ///
299    /// A `BoxPredicate` wrapping this predicate.
300    fn into_box(self) -> BoxPredicate<T>
301    where
302        Self: Sized + 'static,
303    {
304        BoxPredicate::new(move |value: &T| self.test(value))
305    }
306
307    /// Converts this predicate into an `RcPredicate`.
308    ///
309    /// The default implementation wraps the predicate in a closure that
310    /// calls the `test` method. Concrete types may override this with
311    /// more efficient implementations.
312    ///
313    /// # Returns
314    ///
315    /// An `RcPredicate` wrapping this predicate.
316    fn into_rc(self) -> RcPredicate<T>
317    where
318        Self: Sized + 'static,
319    {
320        RcPredicate::new(move |value: &T| self.test(value))
321    }
322
323    /// Converts this predicate into an `ArcPredicate`.
324    ///
325    /// The default implementation wraps the predicate in a closure that
326    /// calls the `test` method. Concrete types may override this with
327    /// more efficient implementations.
328    ///
329    /// # Returns
330    ///
331    /// An `ArcPredicate` wrapping this predicate.
332    fn into_arc(self) -> ArcPredicate<T>
333    where
334        Self: Sized + Send + Sync + 'static,
335    {
336        ArcPredicate::new(move |value: &T| self.test(value))
337    }
338
339    /// Converts this predicate into a closure that can be used directly
340    /// with standard library methods.
341    ///
342    /// This method consumes the predicate and returns a closure with
343    /// signature `Fn(&T) -> bool`. Since `Fn` is a subtrait of `FnMut`,
344    /// the returned closure can be used in any context that requires
345    /// either `Fn(&T) -> bool` or `FnMut(&T) -> bool`, making it
346    /// compatible with methods like `Iterator::filter`,
347    /// `Iterator::filter_map`, `Vec::retain`, and similar standard
348    /// library APIs.
349    ///
350    /// The default implementation returns a closure that calls the
351    /// `test` method. Concrete types may override this with more
352    /// efficient implementations.
353    ///
354    /// # Returns
355    ///
356    /// A closure implementing `Fn(&T) -> bool` (also usable as
357    /// `FnMut(&T) -> bool`).
358    ///
359    /// # Examples
360    ///
361    /// ## Using with `Iterator::filter` (requires `FnMut`)
362    ///
363    /// ```rust
364    /// use qubit_function::{Predicate, BoxPredicate};
365    ///
366    /// let pred = BoxPredicate::new(|x: &i32| *x > 0);
367    ///
368    /// let numbers = vec![-2, -1, 0, 1, 2, 3];
369    /// let positives: Vec<_> = numbers.iter()
370    ///     .copied()
371    ///     .filter(pred.into_fn())
372    ///     .collect();
373    /// assert_eq!(positives, vec![1, 2, 3]);
374    /// ```
375    ///
376    /// ## Using with `Vec::retain` (requires `FnMut`)
377    ///
378    /// ```rust
379    /// use qubit_function::{Predicate, BoxPredicate};
380    ///
381    /// let pred = BoxPredicate::new(|x: &i32| *x % 2 == 0);
382    /// let mut numbers = vec![1, 2, 3, 4, 5, 6];
383    /// numbers.retain(pred.into_fn());
384    /// assert_eq!(numbers, vec![2, 4, 6]);
385    /// ```
386    fn into_fn(self) -> impl Fn(&T) -> bool
387    where
388        Self: Sized + 'static,
389    {
390        move |value: &T| self.test(value)
391    }
392
393    /// Converts a reference to this predicate into a `BoxPredicate`.
394    ///
395    /// This method clones the predicate and then converts it to a
396    /// `BoxPredicate`. The original predicate remains usable after this call.
397    ///
398    /// # Returns
399    ///
400    /// A `BoxPredicate` wrapping a clone of this predicate.
401    fn to_box(&self) -> BoxPredicate<T>
402    where
403        Self: Clone + Sized + 'static,
404    {
405        self.clone().into_box()
406    }
407
408    /// Converts a reference to this predicate into an `RcPredicate`.
409    ///
410    /// This method clones the predicate and then converts it to an
411    /// `RcPredicate`. The original predicate remains usable after this call.
412    ///
413    /// # Returns
414    ///
415    /// An `RcPredicate` wrapping a clone of this predicate.
416    fn to_rc(&self) -> RcPredicate<T>
417    where
418        Self: Clone + Sized + 'static,
419    {
420        self.clone().into_rc()
421    }
422
423    /// Converts a reference to this predicate into an `ArcPredicate`.
424    ///
425    /// This method clones the predicate and then converts it to an
426    /// `ArcPredicate`. The original predicate remains usable after this call.
427    ///
428    /// # Returns
429    ///
430    /// An `ArcPredicate` wrapping a clone of this predicate.
431    fn to_arc(&self) -> ArcPredicate<T>
432    where
433        Self: Clone + Sized + Send + Sync + 'static,
434    {
435        self.clone().into_arc()
436    }
437
438    /// Converts a reference to this predicate into a closure that can be
439    /// used directly with standard library methods.
440    ///
441    /// This method clones the predicate and then converts it to a closure.
442    /// The original predicate remains usable after this call.
443    ///
444    /// The returned closure has signature `Fn(&T) -> bool`. Since `Fn` is a
445    /// subtrait of `FnMut`, it can be used in any context that requires
446    /// either `Fn(&T) -> bool` or `FnMut(&T) -> bool`, making it compatible
447    /// with methods like `Iterator::filter`, `Iterator::filter_map`,
448    /// `Vec::retain`, and similar standard library APIs.
449    ///
450    /// # Returns
451    ///
452    /// A closure implementing `Fn(&T) -> bool` (also usable as
453    /// `FnMut(&T) -> bool`).
454    fn to_fn(&self) -> impl Fn(&T) -> bool
455    where
456        Self: Clone + Sized + 'static,
457    {
458        self.clone().into_fn()
459    }
460}