qubit_function/functions/stateful_mutating_function/arc_stateful_mutating_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 `ArcStatefulMutatingFunction` public type.
12
13#![allow(unused_imports)]
14
15use super::*;
16
17// =======================================================================
18// 5. ArcStatefulMutatingFunction - Thread-Safe Shared Ownership
19// =======================================================================
20
21/// ArcStatefulMutatingFunction struct
22///
23/// A stateful mutating function implementation based on
24/// `Arc<Mutex<dyn FnMut(&mut T) -> R + Send>>` for thread-safe shared
25/// ownership scenarios. This type allows the function to be safely shared
26/// and used across multiple threads.
27///
28/// # Features
29///
30/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
31/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
32/// - **Stateful**: Can modify captured environment (uses `FnMut`)
33/// - **Chainable**: Method chaining via `&self` (non-consuming)
34///
35/// # Use Cases
36///
37/// Choose `ArcStatefulMutatingFunction` when:
38/// - The function needs to be shared across multiple threads for stateful
39/// operations
40/// - Concurrent task processing (e.g., thread pools)
41/// - Thread safety is required (Send + Sync)
42///
43/// # Examples
44///
45/// ```rust
46/// use qubit_function::{StatefulMutatingFunction,
47/// ArcStatefulMutatingFunction};
48///
49/// let counter = {
50/// let mut count = 0;
51/// ArcStatefulMutatingFunction::new(move |x: &mut i32| {
52/// count += 1;
53/// *x *= 2;
54/// count
55/// })
56/// };
57/// let mut clone = counter.clone();
58///
59/// let mut value = 5;
60/// assert_eq!(clone.apply(&mut value), 1);
61/// ```
62///
63pub struct ArcStatefulMutatingFunction<T, R> {
64 pub(super) function: ArcStatefulMutatingFunctionFn<T, R>,
65 pub(super) name: Option<String>,
66}
67
68impl<T, R> ArcStatefulMutatingFunction<T, R> {
69 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
70 impl_function_common_methods!(
71 ArcStatefulMutatingFunction<T, R>,
72 (FnMut(&mut T) -> R + Send + 'static),
73 |f| Arc::new(Mutex::new(f))
74 );
75
76 // Generates: when(), and_then(), compose()
77 impl_shared_function_methods!(
78 ArcStatefulMutatingFunction<T, R>,
79 ArcConditionalStatefulMutatingFunction,
80 into_arc,
81 Function, // chains a non-mutating function after this mutating function
82 Send + Sync + 'static
83 );
84}
85
86// Generates: Clone implementation for ArcStatefulMutatingFunction<T, R>
87impl_function_clone!(ArcStatefulMutatingFunction<T, R>);
88
89// Generates: Debug and Display implementations for ArcStatefulMutatingFunction<T, R>
90impl_function_debug_display!(ArcStatefulMutatingFunction<T, R>);
91
92// Generates: identity() method for ArcStatefulMutatingFunction<T, T>
93impl_function_identity_method!(ArcStatefulMutatingFunction<T, T>, mutating);
94
95// Implement StatefulMutatingFunction trait for ArcStatefulMutatingFunction<T, R>
96impl<T, R> StatefulMutatingFunction<T, R> for ArcStatefulMutatingFunction<T, R> {
97 fn apply(&mut self, t: &mut T) -> R {
98 (self.function.lock())(t)
99 }
100
101 // Use macro to implement conversion methods
102 impl_arc_conversions!(
103 ArcStatefulMutatingFunction<T, R>,
104 BoxStatefulMutatingFunction,
105 RcStatefulMutatingFunction,
106 BoxMutatingFunctionOnce,
107 FnMut(input: &mut T) -> R
108 );
109}
110
111// =======================================================================
112// 6. Implement StatefulMutatingFunction trait for closures
113// =======================================================================
114
115impl<T, R, F> StatefulMutatingFunction<T, R> for F
116where
117 F: FnMut(&mut T) -> R,
118{
119 fn apply(&mut self, input: &mut T) -> R {
120 self(input)
121 }
122
123 fn into_box(self) -> BoxStatefulMutatingFunction<T, R>
124 where
125 Self: Sized + 'static,
126 {
127 BoxStatefulMutatingFunction::new(self)
128 }
129
130 fn into_rc(self) -> RcStatefulMutatingFunction<T, R>
131 where
132 Self: Sized + 'static,
133 {
134 RcStatefulMutatingFunction::new(self)
135 }
136
137 fn into_arc(self) -> ArcStatefulMutatingFunction<T, R>
138 where
139 Self: Sized + Send + 'static,
140 {
141 ArcStatefulMutatingFunction::new(self)
142 }
143
144 fn into_fn(self) -> impl FnMut(&mut T) -> R
145 where
146 Self: Sized + 'static,
147 {
148 self
149 }
150
151 fn to_box(&self) -> BoxStatefulMutatingFunction<T, R>
152 where
153 Self: Sized + Clone + 'static,
154 {
155 let cloned = self.clone();
156 BoxStatefulMutatingFunction::new(cloned)
157 }
158
159 fn to_rc(&self) -> RcStatefulMutatingFunction<T, R>
160 where
161 Self: Sized + Clone + 'static,
162 {
163 let cloned = self.clone();
164 RcStatefulMutatingFunction::new(cloned)
165 }
166
167 fn to_arc(&self) -> ArcStatefulMutatingFunction<T, R>
168 where
169 Self: Sized + Clone + Send + 'static,
170 {
171 let cloned = self.clone();
172 ArcStatefulMutatingFunction::new(cloned)
173 }
174
175 fn to_fn(&self) -> impl FnMut(&mut T) -> R
176 where
177 Self: Sized + Clone + 'static,
178 {
179 self.clone()
180 }
181
182 fn into_once(self) -> BoxMutatingFunctionOnce<T, R>
183 where
184 Self: Sized + 'static,
185 {
186 BoxMutatingFunctionOnce::new(self)
187 }
188
189 fn to_once(&self) -> BoxMutatingFunctionOnce<T, R>
190 where
191 Self: Sized + Clone + 'static,
192 {
193 BoxMutatingFunctionOnce::new(self.clone())
194 }
195}