qubit_function/functions/stateful_function.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//! # StatefulFunction Types
11//!
12//! Provides Rust implementations of stateful function traits for stateful value
13//! transformation. StatefulFunctions consume input values (taking ownership) and
14//! produce output values while allowing internal state modification.
15//!
16//! It is similar to the `FnMut(&T) -> R` trait in the standard library.
17//!
18//! This module provides the `StatefulFunction<T, R>` trait and three implementations:
19//!
20//! - [`BoxStatefulFunction`]: Single ownership, not cloneable
21//! - [`ArcStatefulFunction`]: Thread-safe shared ownership, cloneable
22//! - [`RcStatefulFunction`]: Single-threaded shared ownership, cloneable
23//!
24use std::cell::RefCell;
25use std::rc::Rc;
26use std::sync::Arc;
27
28use parking_lot::Mutex;
29
30use crate::functions::{
31 function_once::BoxFunctionOnce,
32 macros::{
33 impl_box_conditional_function,
34 impl_box_function_methods,
35 impl_conditional_function_clone,
36 impl_conditional_function_debug_display,
37 impl_fn_ops_trait,
38 impl_function_clone,
39 impl_function_common_methods,
40 impl_function_constant_method,
41 impl_function_debug_display,
42 impl_function_identity_method,
43 impl_shared_conditional_function,
44 impl_shared_function_methods,
45 },
46};
47use crate::macros::{
48 impl_arc_conversions,
49 impl_box_conversions,
50 impl_rc_conversions,
51};
52use crate::predicates::predicate::{
53 ArcPredicate,
54 BoxPredicate,
55 Predicate,
56 RcPredicate,
57};
58
59mod box_stateful_function;
60pub use box_stateful_function::BoxStatefulFunction;
61mod rc_stateful_function;
62pub use rc_stateful_function::RcStatefulFunction;
63mod arc_stateful_function;
64pub use arc_stateful_function::ArcStatefulFunction;
65mod box_conditional_stateful_function;
66pub use box_conditional_stateful_function::BoxConditionalStatefulFunction;
67mod rc_conditional_stateful_function;
68pub use rc_conditional_stateful_function::RcConditionalStatefulFunction;
69mod arc_conditional_stateful_function;
70pub use arc_conditional_stateful_function::ArcConditionalStatefulFunction;
71mod fn_stateful_function_ops;
72pub use fn_stateful_function_ops::FnStatefulFunctionOps;
73
74// ============================================================================
75// Core Trait
76// ============================================================================
77
78/// StatefulFunction trait - transforms values from type T to type R with state
79///
80/// Defines the behavior of a stateful transformation: converting a value
81/// of type `T` to a value of type `R` by consuming the input while
82/// allowing modification of internal state. This is analogous to
83/// `FnMut(&T) -> R` in Rust's standard library.
84///
85/// # Type Parameters
86///
87/// * `T` - The type of the input value (consumed)
88/// * `R` - The type of the output value
89///
90pub trait StatefulFunction<T, R> {
91 /// Applies the mapping to the input value to produce an output value
92 ///
93 /// # Parameters
94 ///
95 /// * `t` - The input value to transform (consumed)
96 ///
97 /// # Returns
98 ///
99 /// The transformed output value
100 fn apply(&mut self, t: &T) -> R;
101
102 /// Converts to BoxStatefulFunction
103 ///
104 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
105 /// after calling this method.
106 ///
107 /// # Returns
108 ///
109 /// Returns `BoxStatefulFunction<T, R>`
110 ///
111 /// # Default Implementation
112 ///
113 /// The default implementation wraps `self` in a `BoxStatefulFunction` by
114 /// creating a new closure that calls `self.apply()`. This is a lightweight
115 /// adapter, but it is not strictly zero-cost.
116 ///
117 /// # Examples
118 ///
119 /// ```rust
120 /// use qubit_function::{StatefulFunction, BoxStatefulFunction};
121 ///
122 /// struct CustomStatefulFunction {
123 /// multiplier: i32,
124 /// }
125 ///
126 /// impl StatefulFunction<i32, i32> for CustomStatefulFunction {
127 /// fn apply(&mut self, input: &i32) -> i32 {
128 /// self.multiplier += 1;
129 /// input * self.multiplier
130 /// }
131 /// }
132 ///
133 /// let function = CustomStatefulFunction { multiplier: 0 };
134 /// let mut boxed = function.into_box();
135 /// assert_eq!(boxed.apply(&10), 10); // 10 * 1
136 /// assert_eq!(boxed.apply(&10), 20); // 10 * 2
137 /// ```
138 fn into_box(mut self) -> BoxStatefulFunction<T, R>
139 where
140 Self: Sized + 'static,
141 {
142 BoxStatefulFunction::new(move |t| self.apply(t))
143 }
144
145 /// Converts to RcStatefulFunction
146 ///
147 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
148 /// after calling this method.
149 ///
150 /// # Returns
151 ///
152 /// Returns `RcStatefulFunction<T, R>`
153 ///
154 /// # Default Implementation
155 ///
156 /// The default implementation first converts to `BoxStatefulFunction` using
157 /// `into_box()`, then wraps it in `RcStatefulFunction`. Specific implementations
158 /// may override this for better efficiency.
159 ///
160 /// # Examples
161 ///
162 /// ```rust
163 /// use qubit_function::{StatefulFunction, RcStatefulFunction};
164 ///
165 /// struct CustomStatefulFunction {
166 /// multiplier: i32,
167 /// }
168 ///
169 /// impl StatefulFunction<i32, i32> for CustomStatefulFunction {
170 /// fn apply(&mut self, input: &i32) -> i32 {
171 /// self.multiplier += 1;
172 /// input * self.multiplier
173 /// }
174 /// }
175 ///
176 /// let function = CustomStatefulFunction { multiplier: 0 };
177 /// let mut rc_function = function.into_rc();
178 /// assert_eq!(rc_function.apply(&10), 10); // 10 * 1
179 /// assert_eq!(rc_function.apply(&10), 20); // 10 * 2
180 /// ```
181 fn into_rc(mut self) -> RcStatefulFunction<T, R>
182 where
183 Self: Sized + 'static,
184 {
185 RcStatefulFunction::new(move |t| self.apply(t))
186 }
187
188 /// Converts to ArcStatefulFunction
189 ///
190 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
191 /// after calling this method.
192 ///
193 /// # Returns
194 ///
195 /// Returns `ArcStatefulFunction<T, R>`
196 ///
197 /// # Default Implementation
198 ///
199 /// The default implementation wraps `self` in an `ArcStatefulFunction` by creating
200 /// a new closure that calls `self.apply()`. Note that this requires `self`
201 /// to implement `Send` due to Arc's thread-safety requirements.
202 ///
203 /// # Examples
204 ///
205 /// ```rust
206 /// use qubit_function::{StatefulFunction, ArcStatefulFunction};
207 ///
208 /// struct CustomStatefulFunction {
209 /// multiplier: i32,
210 /// }
211 ///
212 /// impl StatefulFunction<i32, i32> for CustomStatefulFunction {
213 /// fn apply(&mut self, input: &i32) -> i32 {
214 /// self.multiplier += 1;
215 /// input * self.multiplier
216 /// }
217 /// }
218 ///
219 /// let function = CustomStatefulFunction { multiplier: 0 };
220 /// let mut arc_function = function.into_arc();
221 /// assert_eq!(arc_function.apply(&10), 10); // 10 * 1
222 /// assert_eq!(arc_function.apply(&10), 20); // 10 * 2
223 /// ```
224 fn into_arc(mut self) -> ArcStatefulFunction<T, R>
225 where
226 Self: Sized + Send + 'static,
227 {
228 ArcStatefulFunction::new(move |t| self.apply(t))
229 }
230
231 /// Converts to a closure implementing `FnMut(&T) -> R`
232 ///
233 /// **⚠️ Consumes `self`**: The original stateful function becomes unavailable
234 /// after calling this method.
235 ///
236 /// # Returns
237 ///
238 /// Returns an implementation of `FnMut(&T) -> R`
239 ///
240 /// # Default Implementation
241 ///
242 /// The default implementation creates a new closure that calls `self.apply()`.
243 /// Specific implementations may override this for better efficiency.
244 ///
245 /// # Examples
246 ///
247 /// ```rust
248 /// use qubit_function::{StatefulFunction, BoxStatefulFunction};
249 ///
250 /// let function = BoxStatefulFunction::new(|x: &i32| x * 2);
251 /// let mut closure = function.into_fn();
252 /// assert_eq!(closure(&10), 20);
253 /// assert_eq!(closure(&15), 30);
254 /// ```
255 fn into_fn(mut self) -> impl FnMut(&T) -> R
256 where
257 Self: Sized + 'static,
258 {
259 move |t| self.apply(t)
260 }
261
262 /// Converts to a mutable closure (`FnMut`) with an explicit method name.
263 ///
264 /// This is a naming alias of [`StatefulFunction::into_fn`] to make the
265 /// mutability of the returned closure explicit.
266 fn into_mut_fn(self) -> impl FnMut(&T) -> R
267 where
268 Self: Sized + 'static,
269 {
270 self.into_fn()
271 }
272
273 /// Convert to StatefulFunctionOnce
274 ///
275 /// **⚠️ Consumes `self`**: The original function will be unavailable
276 /// after calling this method.
277 ///
278 /// Converts a reusable stateful function to a one-time function that
279 /// consumes itself on use. This enables passing `StatefulFunction` to
280 /// functions that require `StatefulFunctionOnce`.
281 ///
282 /// # Returns
283 ///
284 /// Returns a `BoxFunctionOnce<T, R>`
285 ///
286 /// # Examples
287 ///
288 /// ```rust
289 /// use qubit_function::{FunctionOnce, StatefulFunction,
290 /// RcStatefulFunction};
291 ///
292 /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) {
293 /// let result = func.apply(value);
294 /// println!("Result: {}", result);
295 /// }
296 ///
297 /// let func = RcStatefulFunction::new(|x: &i32| x * 2);
298 /// takes_once(func.into_once(), &5);
299 /// ```
300 fn into_once(mut self) -> BoxFunctionOnce<T, R>
301 where
302 Self: Sized + 'static,
303 {
304 BoxFunctionOnce::new(move |t| self.apply(t))
305 }
306
307 /// Non-consuming conversion to `BoxStatefulFunction`.
308 ///
309 /// Default implementation requires `Self: Clone` and wraps a cloned
310 /// instance in a `RefCell` so the returned stateful function can mutate state
311 /// across calls.
312 fn to_box(&self) -> BoxStatefulFunction<T, R>
313 where
314 Self: Clone + 'static,
315 {
316 self.clone().into_box()
317 }
318
319 /// Non-consuming conversion to `RcStatefulFunction`.
320 ///
321 /// Default implementation clones `self` into an `Rc<RefCell<_>>` so the
322 /// resulting stateful function can be shared within a single thread.
323 fn to_rc(&self) -> RcStatefulFunction<T, R>
324 where
325 Self: Clone + 'static,
326 {
327 self.clone().into_rc()
328 }
329
330 /// Non-consuming conversion to `ArcStatefulFunction` (thread-safe).
331 ///
332 /// Default implementation requires `Self: Clone + Send + Sync` and wraps
333 /// the cloned instance in `Arc<Mutex<_>>` so it can be used across
334 /// threads.
335 fn to_arc(&self) -> ArcStatefulFunction<T, R>
336 where
337 Self: Clone + Send + 'static,
338 {
339 self.clone().into_arc()
340 }
341
342 /// Non-consuming conversion to a closure (`FnMut(&T) -> R`).
343 ///
344 /// Default implementation clones `self` into a `RefCell` and returns a
345 /// closure that calls `apply` on the interior mutable value.
346 fn to_fn(&self) -> impl FnMut(&T) -> R
347 where
348 Self: Sized + Clone + 'static,
349 {
350 self.clone().into_fn()
351 }
352
353 /// Non-consuming conversion to a mutable closure (`FnMut`) with an explicit
354 /// method name.
355 ///
356 /// This is a naming alias of [`StatefulFunction::to_fn`] and preserves the
357 /// same clone-based behavior.
358 fn to_mut_fn(&self) -> impl FnMut(&T) -> R
359 where
360 Self: Sized + Clone + 'static,
361 {
362 self.to_fn()
363 }
364
365 /// Convert to StatefulFunctionOnce without consuming self
366 ///
367 /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
368 /// Clones the current function and converts the clone to a one-time function.
369 ///
370 /// # Returns
371 ///
372 /// Returns a `BoxFunctionOnce<T, R>`
373 ///
374 /// # Examples
375 ///
376 /// ```rust
377 /// use qubit_function::{FunctionOnce, StatefulFunction,
378 /// RcStatefulFunction};
379 ///
380 /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) {
381 /// let result = func.apply(value);
382 /// println!("Result: {}", result);
383 /// }
384 ///
385 /// let func = RcStatefulFunction::new(|x: &i32| x * 2);
386 /// takes_once(func.to_once(), &5);
387 /// ```
388 fn to_once(&self) -> BoxFunctionOnce<T, R>
389 where
390 Self: Clone + 'static,
391 {
392 self.clone().into_once()
393 }
394}