Skip to main content

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}