Skip to main content

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