Skip to main content

qubit_function/predicates/
stateful_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//! # StatefulPredicate Abstraction
11//!
12//! Provides predicate wrappers for closures that implement
13//! `FnMut(&T) -> bool`. A stateful predicate can update its own internal
14//! state while testing borrowed input values.
15//!
16//! Use [`Predicate`](crate::Predicate) for immutable `Fn(&T) -> bool`
17//! predicates and `StatefulPredicate` when the predicate needs native
18//! `FnMut` semantics, such as counters, rolling windows, sampling, or
19//! stateful filters.
20//!
21use std::cell::RefCell;
22use std::rc::Rc;
23use std::sync::Arc;
24
25use parking_lot::Mutex;
26
27use crate::macros::{
28    impl_arc_conversions,
29    impl_box_conversions,
30    impl_rc_conversions,
31};
32use crate::predicates::macros::{
33    constants::{
34        ALWAYS_FALSE_NAME,
35        ALWAYS_TRUE_NAME,
36    },
37    impl_predicate_clone,
38    impl_predicate_common_methods,
39    impl_predicate_debug_display,
40};
41
42mod arc_stateful_predicate;
43pub use arc_stateful_predicate::ArcStatefulPredicate;
44mod box_stateful_predicate;
45pub use box_stateful_predicate::BoxStatefulPredicate;
46mod fn_stateful_predicate_ops;
47pub use fn_stateful_predicate_ops::FnStatefulPredicateOps;
48mod rc_stateful_predicate;
49pub use rc_stateful_predicate::RcStatefulPredicate;
50
51/// A stateful predicate trait for testing values with mutable internal state.
52///
53/// This trait represents closures and wrapper types equivalent to
54/// `FnMut(&T) -> bool`: each call borrows the predicate mutably so the
55/// predicate can update counters, caches, rolling state, or other internal
56/// data while leaving the tested value borrowed immutably.
57///
58/// # Type Parameters
59///
60/// * `T` - The type of the value being tested.
61pub trait StatefulPredicate<T> {
62    /// Tests whether the given value satisfies this predicate.
63    ///
64    /// The method takes `&mut self` because evaluating the predicate may
65    /// update internal state. The tested value itself is only borrowed
66    /// immutably and is not modified by this API.
67    ///
68    /// # Parameters
69    ///
70    /// * `value` - The value to test.
71    ///
72    /// # Returns
73    ///
74    /// `true` if the value satisfies this predicate, `false` otherwise.
75    fn test(&mut self, value: &T) -> bool;
76
77    /// Converts this predicate into a `BoxStatefulPredicate`.
78    ///
79    /// This consumes `self` and wraps it in a single-owner stateful
80    /// predicate. The returned wrapper forwards each call to this
81    /// predicate's [`test`](StatefulPredicate::test) method.
82    ///
83    /// # Returns
84    ///
85    /// A `BoxStatefulPredicate` wrapping this predicate.
86    fn into_box(mut self) -> BoxStatefulPredicate<T>
87    where
88        Self: Sized + 'static,
89    {
90        BoxStatefulPredicate::new(move |value: &T| self.test(value))
91    }
92
93    /// Converts this predicate into an `RcStatefulPredicate`.
94    ///
95    /// This consumes `self` and wraps it in a single-threaded shared
96    /// stateful predicate using `Rc<RefCell<_>>`.
97    ///
98    /// # Returns
99    ///
100    /// An `RcStatefulPredicate` wrapping this predicate.
101    fn into_rc(mut self) -> RcStatefulPredicate<T>
102    where
103        Self: Sized + 'static,
104    {
105        RcStatefulPredicate::new(move |value: &T| self.test(value))
106    }
107
108    /// Converts this predicate into an `ArcStatefulPredicate`.
109    ///
110    /// This consumes `self` and wraps it in a thread-safe shared stateful
111    /// predicate using `Arc<Mutex<_>>`. The wrapped predicate must be
112    /// `Send` so it can be stored behind the thread-safe wrapper.
113    ///
114    /// # Returns
115    ///
116    /// An `ArcStatefulPredicate` wrapping this predicate.
117    fn into_arc(mut self) -> ArcStatefulPredicate<T>
118    where
119        Self: Sized + Send + 'static,
120    {
121        ArcStatefulPredicate::new(move |value: &T| self.test(value))
122    }
123
124    /// Converts this predicate into a closure implementing `FnMut(&T) -> bool`.
125    ///
126    /// This consumes `self` and returns a mutable closure that forwards each
127    /// call to [`test`](StatefulPredicate::test).
128    ///
129    /// # Returns
130    ///
131    /// A closure implementing `FnMut(&T) -> bool`.
132    fn into_fn(mut self) -> impl FnMut(&T) -> bool
133    where
134        Self: Sized + 'static,
135    {
136        move |value: &T| self.test(value)
137    }
138
139    /// Converts a clone of this predicate into a `BoxStatefulPredicate`.
140    ///
141    /// The original predicate remains available after this call. The cloned
142    /// predicate owns independent state unless its clone implementation shares
143    /// state internally.
144    ///
145    /// # Returns
146    ///
147    /// A `BoxStatefulPredicate` wrapping a clone of this predicate.
148    fn to_box(&self) -> BoxStatefulPredicate<T>
149    where
150        Self: Clone + Sized + 'static,
151    {
152        self.clone().into_box()
153    }
154
155    /// Converts a clone of this predicate into an `RcStatefulPredicate`.
156    ///
157    /// The original predicate remains available after this call. The cloned
158    /// predicate owns independent state unless its clone implementation shares
159    /// state internally.
160    ///
161    /// # Returns
162    ///
163    /// An `RcStatefulPredicate` wrapping a clone of this predicate.
164    fn to_rc(&self) -> RcStatefulPredicate<T>
165    where
166        Self: Clone + Sized + 'static,
167    {
168        self.clone().into_rc()
169    }
170
171    /// Converts a clone of this predicate into an `ArcStatefulPredicate`.
172    ///
173    /// The original predicate remains available after this call. The cloned
174    /// predicate must be `Send` so it can be stored behind the thread-safe
175    /// wrapper.
176    ///
177    /// # Returns
178    ///
179    /// An `ArcStatefulPredicate` wrapping a clone of this predicate.
180    fn to_arc(&self) -> ArcStatefulPredicate<T>
181    where
182        Self: Clone + Sized + Send + 'static,
183    {
184        self.clone().into_arc()
185    }
186
187    /// Converts a clone of this predicate into a mutable closure.
188    ///
189    /// The original predicate remains available after this call. The cloned
190    /// predicate owns independent state unless its clone implementation shares
191    /// state internally.
192    ///
193    /// # Returns
194    ///
195    /// A closure implementing `FnMut(&T) -> bool`.
196    fn to_fn(&self) -> impl FnMut(&T) -> bool
197    where
198        Self: Clone + Sized + 'static,
199    {
200        let mut predicate = self.clone();
201        move |value: &T| predicate.test(value)
202    }
203}