qubit_function/consumers/consumer/rc_consumer.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `RcConsumer` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// ============================================================================
16// 3. RcConsumer - Single-threaded Shared Ownership Implementation
17// ============================================================================
18
19/// RcConsumer struct
20///
21/// Non-mutating consumer implementation based on `Rc<dyn Fn(&T)>` for
22/// single-threaded shared ownership scenarios. The wrapper does not need
23/// `RefCell` because it only invokes a shared `Fn`.
24///
25/// # Features
26///
27/// - **Shared Ownership**: Cloneable through `Rc`, allows multiple owners
28/// - **Single-threaded**: Not thread-safe, cannot be sent across threads
29/// - **No Wrapper Interior Mutability Overhead**: No RefCell needed by the
30/// wrapper
31/// - **Non-consuming API**: `and_then` borrows `&self`, original object remains
32/// usable
33///
34/// # Use Cases
35///
36/// Choose `RcConsumer` when:
37/// - Need to share non-mutating consumer within a single thread
38/// - Pure observation operations, performance critical
39/// - Event handling in single-threaded UI frameworks
40///
41/// # Performance Advantages
42///
43/// `RcConsumer` has neither Arc's atomic operation overhead nor
44/// RefCell's runtime borrow checking overhead, making it the most performant of
45/// the three non-mutating consumers.
46///
47/// # Examples
48///
49/// ```rust
50/// use qubit_function::{Consumer, RcConsumer};
51///
52/// let consumer = RcConsumer::new(|x: &i32| {
53/// println!("Observed: {}", x);
54/// });
55/// let clone = consumer.clone();
56///
57/// consumer.accept(&5);
58/// clone.accept(&10);
59/// ```
60///
61/// # Author
62///
63/// Haixing Hu
64pub struct RcConsumer<T> {
65 pub(super) function: Rc<dyn Fn(&T)>,
66 pub(super) name: Option<String>,
67}
68
69impl<T> RcConsumer<T> {
70 // Generates: new(), new_with_name(), name(), set_name(), noop()
71 impl_consumer_common_methods!(RcConsumer<T>, (Fn(&T) + 'static), |f| Rc::new(f));
72
73 // Generates: when() and and_then() methods that borrow &self (Rc can clone)
74 impl_shared_consumer_methods!(
75 RcConsumer<T>,
76 RcConditionalConsumer,
77 into_rc,
78 Consumer,
79 'static
80 );
81}
82
83impl<T> Consumer<T> for RcConsumer<T> {
84 fn accept(&self, value: &T) {
85 (self.function)(value)
86 }
87
88 // Use macro to implement conversion methods
89 impl_rc_conversions!(
90 RcConsumer<T>,
91 BoxConsumer,
92 BoxConsumerOnce,
93 Fn(t: &T)
94 );
95}
96
97// Use macro to generate Clone implementation
98impl_consumer_clone!(RcConsumer<T>);
99
100// Use macro to generate Debug and Display implementations
101impl_consumer_debug_display!(RcConsumer<T>);