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