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