Skip to main content

qubit_function/consumers/stateful_bi_consumer/
box_stateful_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 `BoxStatefulBiConsumer` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// =======================================================================
16// 2. BoxStatefulBiConsumer - Single Ownership Implementation
17// =======================================================================
18
19/// BoxStatefulBiConsumer struct
20///
21/// A bi-consumer implementation based on `Box<dyn FnMut(&T, &U)>` for
22/// single ownership scenarios. This is the simplest and most efficient
23/// bi-consumer type when sharing is not required.
24///
25/// # Features
26///
27/// - **Single Ownership**: Not cloneable, ownership moves on use
28/// - **Zero Overhead**: No reference counting or locking
29/// - **Mutable State**: Can modify captured environment via `FnMut`
30/// - **Builder Pattern**: Method chaining consumes `self` naturally
31///
32/// # Use Cases
33///
34/// Choose `BoxStatefulBiConsumer` when:
35/// - The bi-consumer is used only once or in a linear flow
36/// - Building pipelines where ownership naturally flows
37/// - No need to share the consumer across contexts
38/// - Performance is critical and sharing overhead is unacceptable
39///
40/// # Performance
41///
42/// `BoxStatefulBiConsumer` has the best performance among the three bi-consumer
43/// types:
44/// - No reference counting overhead
45/// - No lock acquisition or runtime borrow checking
46/// - Direct function call through vtable
47/// - Minimal memory footprint (single pointer)
48///
49/// # Examples
50///
51/// ```rust
52/// use qubit_function::{BiConsumer, BoxStatefulBiConsumer, StatefulBiConsumer};
53/// use std::sync::{Arc, Mutex};
54///
55/// let log = Arc::new(Mutex::new(Vec::new()));
56/// let l = log.clone();
57/// let mut consumer = BoxStatefulBiConsumer::new(move |x: &i32, y: &i32| {
58///     l.lock().unwrap().push(*x + *y);
59/// });
60/// consumer.accept(&5, &3);
61/// assert_eq!(*log.lock().unwrap(), vec![8]);
62/// ```
63///
64/// # Author
65///
66/// Haixing Hu
67pub struct BoxStatefulBiConsumer<T, U> {
68    pub(super) function: Box<dyn FnMut(&T, &U)>,
69    pub(super) name: Option<String>,
70}
71
72impl<T, U> BoxStatefulBiConsumer<T, U> {
73    // Generates: new(), new_with_name(), name(), set_name(), noop()
74    impl_consumer_common_methods!(
75        BoxStatefulBiConsumer<T, U>,
76        (FnMut(&T, &U) + 'static),
77        |f| Box::new(f)
78    );
79
80    // Generates: when() and and_then() methods that consume self
81    impl_box_consumer_methods!(
82        BoxStatefulBiConsumer<T, U>,
83        BoxConditionalStatefulBiConsumer,
84        StatefulBiConsumer
85    );
86}
87
88impl<T, U> StatefulBiConsumer<T, U> for BoxStatefulBiConsumer<T, U> {
89    fn accept(&mut self, first: &T, second: &U) {
90        (self.function)(first, second)
91    }
92
93    // Generates: into_box(), into_rc(), into_fn(), into_once()
94    impl_box_conversions!(
95        BoxStatefulBiConsumer<T, U>,
96        RcStatefulBiConsumer,
97        FnMut(&T, &U),
98        BoxBiConsumerOnce
99    );
100}
101
102// Use macro to generate Debug and Display implementations
103impl_consumer_debug_display!(BoxStatefulBiConsumer<T, U>);