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| { Arc::new(f) });
75
76 // Generate shared mutator methods (when, and_then, or_else, conversions)
77 impl_shared_mutator_methods!(
78 ArcMutator<T>,
79 ArcConditionalMutator,
80 into_arc,
81 Mutator,
82 Send + Sync + 'static
83 );
84}
85
86impl<T> Mutator<T> for ArcMutator<T> {
87 fn apply(&self, value: &mut T) {
88 (self.function)(value)
89 }
90
91 // Use macro to implement conversion methods
92 impl_arc_conversions!(
93 ArcMutator<T>,
94 BoxMutator,
95 RcMutator,
96 BoxMutatorOnce,
97 Fn(input: &mut T)
98 );
99}
100
101// Generate Clone trait implementation for mutator
102impl_mutator_clone!(ArcMutator<T>);
103
104// Generate Debug and Display trait implementations
105impl_mutator_debug_display!(ArcMutator<T>);
106
107// ============================================================================
108// 6. Implement Mutator trait for closures
109// ============================================================================
110
111impl_closure_trait!(
112 Mutator<T>,
113 apply,
114 BoxMutatorOnce,
115 Fn(value: &mut T)
116);