Skip to main content

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}