Skip to main content

qubit_function/functions/stateful_function/
rc_stateful_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 `RcStatefulFunction` public type.
12
13use super::{
14    BoxFunctionOnce,
15    BoxStatefulFunction,
16    Predicate,
17    Rc,
18    RcConditionalStatefulFunction,
19    RefCell,
20    StatefulFunction,
21    impl_function_clone,
22    impl_function_common_methods,
23    impl_function_constant_method,
24    impl_function_debug_display,
25    impl_function_identity_method,
26    impl_rc_conversions,
27    impl_shared_function_methods,
28};
29
30// ============================================================================
31// RcStatefulFunction - Rc<RefCell<dyn FnMut(&T) -> R>>
32// ============================================================================
33
34/// RcStatefulFunction - single-threaded function wrapper
35///
36/// A single-threaded, clonable function wrapper optimized for scenarios
37/// that require sharing without thread-safety overhead.
38///
39/// # Features
40///
41/// - **Based on**: `Rc<RefCell<dyn FnMut(&T) -> R>>`
42/// - **Ownership**: Shared ownership via reference counting (non-atomic)
43/// - **Reusability**: Can be called multiple times (each call consumes
44///   its input)
45/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
46/// - **Clonable**: Cheap cloning via `Rc::clone`
47/// - **Statefulness**: Can modify internal state between calls
48///
49pub struct RcStatefulFunction<T, R> {
50    pub(super) function: RcStatefulFn<T, R>,
51    pub(super) name: Option<String>,
52}
53
54type RcStatefulFn<T, R> = Rc<RefCell<dyn FnMut(&T) -> R>>;
55
56impl<T, R> RcStatefulFunction<T, R> {
57    // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
58    impl_function_common_methods!(
59        RcStatefulFunction<T, R>,
60        (FnMut(&T) -> R + 'static),
61        |f| Rc::new(RefCell::new(f))
62    );
63
64    // Generates: when(), and_then(), compose()
65    impl_shared_function_methods!(
66        RcStatefulFunction<T, R>,
67        RcConditionalStatefulFunction,
68        into_rc,
69        StatefulFunction,
70        'static
71    );
72}
73
74// Generates: constant() method for RcStatefulFunction<T, R>
75impl_function_constant_method!(RcStatefulFunction<T, R>, 'static);
76
77// Generates: identity() method for RcStatefulFunction<T, T>
78impl_function_identity_method!(RcStatefulFunction<T, T>);
79
80// Generates: Clone implementation for RcStatefulFunction<T, R>
81impl_function_clone!(RcStatefulFunction<T, R>);
82
83// Generates: Debug and Display implementations for RcStatefulFunction<T, R>
84impl_function_debug_display!(RcStatefulFunction<T, R>);
85
86// Implement StatefulFunction trait for RcStatefulFunction<T, R>
87impl<T, R> StatefulFunction<T, R> for RcStatefulFunction<T, R> {
88    fn apply(&mut self, t: &T) -> R {
89        (self.function.borrow_mut())(t)
90    }
91
92    // Use macro to implement conversion methods
93    impl_rc_conversions!(
94        RcStatefulFunction<T, R>,
95        BoxStatefulFunction,
96        BoxFunctionOnce,
97        FnMut(t: &T) -> R
98    );
99}