Skip to main content

qubit_function/mutators/stateful_mutator/
arc_stateful_mutator.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 `ArcStatefulMutator` public type.
12
13#![allow(unused_imports)]
14
15use super::*;
16
17// ============================================================================
18// 4. ArcMutator - Thread-Safe Shared Ownership Implementation
19// ============================================================================
20
21/// ArcMutator struct
22///
23/// A mutator implementation based on `Arc<Mutex<dyn FnMut(&mut T) + Send>>`
24/// for thread-safe shared ownership scenarios. This type allows the mutator
25/// to be safely shared and used across multiple threads.
26///
27/// # Features
28///
29/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
30/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
31/// - **Interior Mutability**: Uses `Mutex` for safe concurrent mutations
32/// - **Mutable State**: Can modify captured environment via `FnMut`
33/// - **Chainable**: Method chaining via `&self` (non-consuming)
34///
35/// # Use Cases
36///
37/// Choose `ArcMutator` when:
38/// - The mutator needs to be shared across multiple threads
39/// - Concurrent task processing (e.g., thread pools)
40/// - Thread safety is required (Send + Sync)
41///
42/// # Examples
43///
44/// ```rust
45/// use qubit_function::{Mutator, ArcMutator};
46///
47/// let mutator = ArcMutator::new(|x: &mut i32| *x *= 2);
48/// let clone = mutator.clone();
49///
50/// let mut value = 5;
51/// let mut m = mutator;
52/// m.apply(&mut value);
53/// assert_eq!(value, 10);
54/// ```
55///
56pub struct ArcStatefulMutator<T> {
57    pub(super) function: ArcMutMutatorFn<T>,
58    pub(super) name: Option<String>,
59}
60
61impl<T> ArcStatefulMutator<T> {
62    impl_mutator_common_methods!(
63        ArcStatefulMutator<T>,
64        (FnMut(&mut T) + Send + 'static),
65        |f| Arc::new(Mutex::new(f))
66    );
67
68    // Generate shared mutator methods (when, and_then, or_else, conversions)
69    impl_shared_mutator_methods!(
70        ArcStatefulMutator<T>,
71        ArcConditionalStatefulMutator,
72        into_arc,
73        StatefulMutator,
74        Send + Sync + 'static
75    );
76}
77
78impl<T> StatefulMutator<T> for ArcStatefulMutator<T> {
79    fn apply(&mut self, value: &mut T) {
80        (self.function.lock())(value)
81    }
82
83    // Use macro to implement conversion methods
84    impl_arc_conversions!(
85        ArcStatefulMutator<T>,
86        BoxStatefulMutator,
87        RcStatefulMutator,
88        BoxMutatorOnce,
89        FnMut(input: &mut T)
90    );
91}
92
93// Use macro to generate Clone implementation
94impl_mutator_clone!(ArcStatefulMutator<T>);
95
96// Generate Debug and Display trait implementations
97impl_mutator_debug_display!(ArcStatefulMutator<T>);
98
99// ============================================================================
100// 5. Implement Mutator trait for closures
101// ============================================================================
102
103impl_closure_trait!(
104    StatefulMutator<T>,
105    apply,
106    BoxMutatorOnce,
107    FnMut(value: &mut T)
108);