qubit_function/functions/stateful_mutating_function/rc_stateful_mutating_function.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 `RcStatefulMutatingFunction` public type.
12
13use super::{
14 BoxMutatingFunctionOnce,
15 BoxStatefulMutatingFunction,
16 Function,
17 Predicate,
18 Rc,
19 RcConditionalStatefulMutatingFunction,
20 RcStatefulMutatingFunctionFn,
21 RefCell,
22 StatefulMutatingFunction,
23 impl_function_clone,
24 impl_function_common_methods,
25 impl_function_debug_display,
26 impl_function_identity_method,
27 impl_rc_conversions,
28 impl_shared_function_methods,
29};
30
31// =======================================================================
32// 4. RcStatefulMutatingFunction - Single-Threaded Shared Ownership
33// =======================================================================
34
35/// RcStatefulMutatingFunction struct
36///
37/// A stateful mutating function implementation based on
38/// `Rc<RefCell<dyn FnMut(&mut T) -> R>>` for single-threaded shared
39/// ownership scenarios. This type allows multiple references to the same
40/// function without the overhead of thread safety.
41///
42/// # Features
43///
44/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
45/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
46/// - **Stateful**: Can modify captured environment (uses `FnMut`)
47/// - **Chainable**: Method chaining via `&self` (non-consuming)
48/// - **Performance**: More efficient than `ArcStatefulMutatingFunction` (no
49/// locking)
50///
51/// # Use Cases
52///
53/// Choose `RcStatefulMutatingFunction` when:
54/// - The function needs to be shared within a single thread for stateful
55/// operations
56/// - Thread safety is not required
57/// - Performance is important (avoiding lock overhead)
58///
59/// # Examples
60///
61/// ```rust
62/// use qubit_function::{StatefulMutatingFunction,
63/// RcStatefulMutatingFunction};
64///
65/// let counter = {
66/// let mut count = 0;
67/// RcStatefulMutatingFunction::new(move |x: &mut i32| {
68/// count += 1;
69/// *x *= 2;
70/// count
71/// })
72/// };
73/// let mut clone = counter.clone();
74///
75/// let mut value = 5;
76/// assert_eq!(clone.apply(&mut value), 1);
77/// ```
78///
79pub struct RcStatefulMutatingFunction<T, R> {
80 pub(super) function: RcStatefulMutatingFunctionFn<T, R>,
81 pub(super) name: Option<String>,
82}
83
84impl<T, R> RcStatefulMutatingFunction<T, R> {
85 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
86 impl_function_common_methods!(
87 RcStatefulMutatingFunction<T, R>,
88 (FnMut(&mut T) -> R + 'static),
89 |f| Rc::new(RefCell::new(f))
90 );
91
92 // Generates: when(), and_then(), compose()
93 impl_shared_function_methods!(
94 RcStatefulMutatingFunction<T, R>,
95 RcConditionalStatefulMutatingFunction,
96 into_rc,
97 Function, // chains a non-mutating function after this mutating function
98 'static
99 );
100}
101
102// Generates: Clone implementation for RcStatefulMutatingFunction<T, R>
103impl_function_clone!(RcStatefulMutatingFunction<T, R>);
104
105// Generates: Debug and Display implementations for RcStatefulMutatingFunction<T, R>
106impl_function_debug_display!(RcStatefulMutatingFunction<T, R>);
107
108// Generates: identity() method for RcStatefulMutatingFunction<T, T>
109impl_function_identity_method!(RcStatefulMutatingFunction<T, T>, mutating);
110
111// Implement StatefulMutatingFunction trait for RcStatefulMutatingFunction<T, R>
112impl<T, R> StatefulMutatingFunction<T, R> for RcStatefulMutatingFunction<T, R> {
113 fn apply(&mut self, t: &mut T) -> R {
114 (self.function.borrow_mut())(t)
115 }
116
117 // Use macro to implement conversion methods
118 impl_rc_conversions!(
119 RcStatefulMutatingFunction<T, R>,
120 BoxStatefulMutatingFunction,
121 BoxMutatingFunctionOnce,
122 FnMut(input: &mut T) -> R
123 );
124}