Skip to main content

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}