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}