Skip to main content

qubit_function/functions/stateful_function/
arc_stateful_function.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `ArcStatefulFunction` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// ============================================================================
16// ArcStatefulFunction - Arc<Mutex<dyn FnMut(&T) -> R + Send>>
17// ============================================================================
18
19/// ArcStatefulFunction - thread-safe function wrapper
20///
21/// A thread-safe, clonable function wrapper suitable for multi-threaded
22/// scenarios. Can be called multiple times and shared across threads
23/// while maintaining internal state.
24///
25/// # Features
26///
27/// - **Based on**: `Arc<Mutex<dyn FnMut(&T) -> R + Send>>`
28/// - **Ownership**: Shared ownership via reference counting
29/// - **Reusability**: Can be called multiple times (each call consumes
30///   its input)
31/// - **Thread Safety**: Thread-safe (`Send` required)
32/// - **Clonable**: Cheap cloning via `Arc::clone`
33/// - **Statefulness**: Can modify internal state between calls
34///
35/// # Author
36///
37/// Haixing Hu
38pub struct ArcStatefulFunction<T, R> {
39    pub(super) function: ArcStatefulFn<T, R>,
40    pub(super) name: Option<String>,
41}
42
43type ArcStatefulFn<T, R> = Arc<Mutex<dyn FnMut(&T) -> R + Send + 'static>>;
44
45impl<T, R> ArcStatefulFunction<T, R> {
46    // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
47    impl_function_common_methods!(
48        ArcStatefulFunction<T, R>,
49        (FnMut(&T) -> R + Send + 'static),
50        |f| Arc::new(Mutex::new(f))
51    );
52
53    // Generates: when(), and_then(), compose()
54    impl_shared_function_methods!(
55        ArcStatefulFunction<T, R>,
56        ArcConditionalStatefulFunction,
57        into_arc,
58        StatefulFunction,
59        Send + Sync + 'static
60    );
61}
62
63// Generates: constant() method for ArcStatefulFunction<T, R>
64impl_function_constant_method!(ArcStatefulFunction<T, R>, Send + Sync + 'static);
65
66// Generates: identity() method for ArcStatefulFunction<T, T>
67impl_function_identity_method!(ArcStatefulFunction<T, T>);
68
69// Generates: Clone implementation for ArcStatefulFunction<T, R>
70impl_function_clone!(ArcStatefulFunction<T, R>);
71
72// Generates: Debug and Display implementations for ArcStatefulFunction<T, R>
73impl_function_debug_display!(ArcStatefulFunction<T, R>);
74
75// Implement StatefulFunction trait for ArcStatefulFunction<T, R>
76impl<T, R> StatefulFunction<T, R> for ArcStatefulFunction<T, R> {
77    fn apply(&mut self, t: &T) -> R {
78        (self.function.lock())(t)
79    }
80
81    // Use macro to implement conversion methods
82    impl_arc_conversions!(
83        ArcStatefulFunction<T, R>,
84        BoxStatefulFunction,
85        RcStatefulFunction,
86        BoxFunctionOnce,
87        FnMut(t: &T) -> R
88    );
89}
90
91// ============================================================================
92// Blanket implementation for standard FnMut trait
93// ============================================================================
94
95/// Implement StatefulFunction<T, R> for any type that implements FnMut(&T) -> R
96///
97/// This allows closures to be used directly with our StatefulFunction trait
98/// without wrapping.
99///
100/// # Examples
101///
102/// ```rust
103/// use qubit_function::StatefulFunction;
104///
105/// let mut counter = 0;
106/// let mut function = |x: &i32| {
107///     counter += 1;
108///     *x + counter
109/// };
110///
111/// assert_eq!(function.apply(&10), 11);
112/// assert_eq!(function.apply(&10), 12);
113/// ```
114///
115/// # Author
116///
117/// Haixing Hu
118impl<F, T, R> StatefulFunction<T, R> for F
119where
120    F: FnMut(&T) -> R,
121{
122    fn apply(&mut self, t: &T) -> R {
123        self(t)
124    }
125
126    fn into_box(self) -> BoxStatefulFunction<T, R>
127    where
128        Self: Sized + 'static,
129    {
130        BoxStatefulFunction::new(self)
131    }
132
133    fn into_rc(self) -> RcStatefulFunction<T, R>
134    where
135        Self: Sized + 'static,
136    {
137        RcStatefulFunction::new(self)
138    }
139
140    fn into_arc(self) -> ArcStatefulFunction<T, R>
141    where
142        Self: Sized + Send + 'static,
143    {
144        ArcStatefulFunction::new(self)
145    }
146
147    fn into_fn(self) -> impl FnMut(&T) -> R
148    where
149        Self: Sized + 'static,
150    {
151        self
152    }
153
154    fn to_box(&self) -> BoxStatefulFunction<T, R>
155    where
156        Self: Sized + Clone + 'static,
157    {
158        self.clone().into_box()
159    }
160
161    fn to_rc(&self) -> RcStatefulFunction<T, R>
162    where
163        Self: Sized + Clone + 'static,
164    {
165        self.clone().into_rc()
166    }
167
168    fn to_arc(&self) -> ArcStatefulFunction<T, R>
169    where
170        Self: Sized + Clone + Send + 'static,
171    {
172        self.clone().into_arc()
173    }
174
175    fn to_fn(&self) -> impl FnMut(&T) -> R
176    where
177        Self: Sized + Clone + 'static,
178    {
179        self.clone()
180    }
181
182    fn into_once(self) -> BoxFunctionOnce<T, R>
183    where
184        Self: Sized + 'static,
185    {
186        BoxFunctionOnce::new(self)
187    }
188
189    fn to_once(&self) -> BoxFunctionOnce<T, R>
190    where
191        Self: Sized + Clone + 'static,
192    {
193        BoxFunctionOnce::new(self.clone())
194    }
195}