qubit_function/mutators/mutator/rc_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 `RcMutator` public type.
12
13use super::{
14 BoxMutator,
15 BoxMutatorOnce,
16 Mutator,
17 Predicate,
18 Rc,
19 RcConditionalMutator,
20 RcMutatorFn,
21 impl_mutator_clone,
22 impl_mutator_common_methods,
23 impl_mutator_debug_display,
24 impl_rc_conversions,
25 impl_shared_mutator_methods,
26};
27
28// ============================================================================
29// 4. RcMutator - Single-Threaded Shared Ownership Implementation
30// ============================================================================
31
32/// RcMutator struct
33///
34/// A stateless mutator implementation based on `Rc<dyn Fn(&mut T)>` for
35/// single-threaded shared ownership scenarios. This type allows multiple
36/// references to the same mutator without the overhead of thread safety.
37///
38/// # Features
39///
40/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
41/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
42/// - **Stateless**: Cannot modify captured environment (uses `Fn` not `FnMut`)
43/// - **Chainable**: Method chaining via `&self` (non-consuming)
44/// - **Performance**: More efficient than `ArcMutator` (no locking)
45///
46/// # Use Cases
47///
48/// Choose `RcMutator` when:
49/// - The mutator needs to be shared within a single thread for stateless operations
50/// - Thread safety is not required
51/// - Performance is important (avoiding lock overhead)
52///
53/// # Examples
54///
55/// ```rust
56/// use qubit_function::{Mutator, RcMutator};
57///
58/// let mutator = RcMutator::new(|x: &mut i32| *x *= 2);
59/// let clone = mutator.clone();
60///
61/// let mut value = 5;
62/// mutator.apply(&mut value);
63/// assert_eq!(value, 10);
64/// ```
65///
66pub struct RcMutator<T> {
67 pub(super) function: RcMutatorFn<T>,
68 pub(super) name: Option<String>,
69}
70
71impl<T> RcMutator<T> {
72 // Generate common mutator methods (new, new_with_name, name, set_name, noop)
73 impl_mutator_common_methods!(RcMutator<T>, (Fn(&mut T) + 'static), |f| Rc::new(f));
74
75 // Generate shared mutator methods (when, and_then, or_else, conversions)
76 impl_shared_mutator_methods!(
77 RcMutator<T>,
78 RcConditionalMutator,
79 into_rc,
80 Mutator,
81 'static
82 );
83}
84
85impl<T> Mutator<T> for RcMutator<T> {
86 fn apply(&self, value: &mut T) {
87 (self.function)(value)
88 }
89
90 // Generate all conversion methods using the unified macro
91 impl_rc_conversions!(
92 RcMutator<T>,
93 BoxMutator,
94 BoxMutatorOnce,
95 Fn(t: &mut T)
96 );
97}
98
99// Generate Clone trait implementation for mutator
100impl_mutator_clone!(RcMutator<T>);
101
102// Generate Debug and Display trait implementations
103impl_mutator_debug_display!(RcMutator<T>);