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