Skip to main content

qubit_function/consumers/bi_consumer/
arc_bi_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 `ArcBiConsumer` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// =======================================================================
16// 4. ArcBiConsumer - Thread-Safe Shared Ownership
17// =======================================================================
18
19/// ArcBiConsumer struct
20///
21/// A non-mutating bi-consumer implementation based on
22/// `Arc<dyn Fn(&T, &U) + Send + Sync>` for thread-safe shared ownership
23/// scenarios. The wrapper does not need `Mutex` because it only invokes a
24/// shared `Fn`.
25///
26/// # Features
27///
28/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
29/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
30/// - **Lock-free Wrapper**: No Mutex protection needed by the wrapper
31/// - **Non-Consuming API**: `and_then` borrows `&self`, original remains
32///   usable
33///
34/// # Use Cases
35///
36/// Choose `ArcBiConsumer` when:
37/// - Need to share non-mutating bi-consumer across multiple threads
38/// - Pure observation operations like logging, monitoring, notifications
39/// - Need high-concurrency reads without lock overhead
40///
41/// # Performance Advantages
42///
43/// Compared to `ArcStatefulBiConsumer`, `ArcBiConsumer` has no Mutex locking
44/// overhead, resulting in better performance in high-concurrency observation
45/// scenarios.
46///
47/// # Examples
48///
49/// ```rust
50/// use qubit_function::{BiConsumer, ArcBiConsumer};
51///
52/// let consumer = ArcBiConsumer::new(|x: &i32, y: &i32| {
53///     println!("Sum: {}", x + y);
54/// });
55/// let clone = consumer.clone();
56///
57/// consumer.accept(&5, &3);
58/// clone.accept(&10, &20);
59/// ```
60///
61/// # Author
62///
63/// Haixing Hu
64pub struct ArcBiConsumer<T, U> {
65    pub(super) function: Arc<ThreadSafeBiConsumerFn<T, U>>,
66    pub(super) name: Option<String>,
67}
68
69impl<T, U> ArcBiConsumer<T, U> {
70    // Generates: new(), new_with_name(), name(), set_name(), noop()
71    impl_consumer_common_methods!(
72        ArcBiConsumer<T, U>,
73        (Fn(&T, &U) + Send + Sync + 'static),
74        |f| Arc::new(f)
75    );
76
77    // Generates: when() and and_then() methods that borrow &self (Arc can clone)
78    impl_shared_consumer_methods!(
79        ArcBiConsumer<T, U>,
80        ArcConditionalBiConsumer,
81        into_arc,
82        BiConsumer,
83        Send + Sync + 'static
84    );
85}
86
87impl<T, U> BiConsumer<T, U> for ArcBiConsumer<T, U> {
88    fn accept(&self, first: &T, second: &U) {
89        (self.function)(first, second)
90    }
91
92    // Use macro to implement conversion methods
93    impl_arc_conversions!(
94        ArcBiConsumer<T, U>,
95        BoxBiConsumer,
96        RcBiConsumer,
97        BoxBiConsumerOnce,
98        Fn(t: &T, u: &U)
99    );
100}
101
102// Use macro to generate Clone implementation
103impl_consumer_clone!(ArcBiConsumer<T, U>);
104
105// Use macro to generate Debug and Display implementations
106impl_consumer_debug_display!(ArcBiConsumer<T, U>);
107
108// =======================================================================
109// 5. Implement BiConsumer trait for closures
110// =======================================================================
111
112// Implements BiConsumer for all Fn(&T, &U)
113impl_closure_trait!(
114    BiConsumer<T, U>,
115    accept,
116    BoxBiConsumerOnce,
117    Fn(first: &T, second: &U)
118);