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}