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