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);