Skip to main content

qubit_function/consumers/bi_consumer_once/
box_bi_consumer_once.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `BoxBiConsumerOnce` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// =======================================================================
16// 2. BoxBiConsumerOnce - Single Ownership Implementation
17// =======================================================================
18
19/// BoxBiConsumerOnce struct
20///
21/// A one-time bi-consumer implementation based on
22/// `Box<dyn FnOnce(&T, &U)>` for single ownership scenarios. This is the
23/// simplest one-time bi-consumer type for truly one-time use.
24///
25/// # Features
26///
27/// - **Single Ownership**: Not cloneable, ownership moves on use
28/// - **Zero Overhead**: No reference counting or locking
29/// - **One-Time Use**: Consumes self on first call
30/// - **Builder Pattern**: Method chaining consumes `self` naturally
31///
32/// # Use Cases
33///
34/// Choose `BoxBiConsumerOnce` when:
35/// - The bi-consumer is truly used only once
36/// - Building pipelines where ownership naturally flows
37/// - The consumer captures values that should be consumed
38/// - Performance is critical and sharing overhead is unacceptable
39///
40/// # Performance
41///
42/// `BoxBiConsumerOnce` has the best performance:
43/// - No reference counting overhead
44/// - No lock acquisition or runtime borrow checking
45/// - Direct function call through vtable
46/// - Minimal memory footprint (single pointer)
47///
48/// # Examples
49///
50/// ```rust
51/// use qubit_function::{BiConsumerOnce, BoxBiConsumerOnce};
52///
53/// let consumer = BoxBiConsumerOnce::new(|x: &i32, y: &i32| {
54///     println!("Sum: {}", x + y);
55/// });
56/// consumer.accept(&5, &3);
57/// ```
58///
59/// # Author
60///
61/// Haixing Hu
62pub struct BoxBiConsumerOnce<T, U> {
63    pub(super) function: Box<BiConsumerOnceFn<T, U>>,
64    pub(super) name: Option<String>,
65}
66
67// All methods require T: 'static and U: 'static because
68// Box<dyn FnOnce(&T, &U)> requires it
69impl<T, U> BoxBiConsumerOnce<T, U> {
70    // Generates: new(), new_with_name(), name(), set_name(), noop()
71    impl_consumer_common_methods!(
72        BoxBiConsumerOnce<T, U>,
73        (FnOnce(&T, &U) + 'static),
74        |f| Box::new(f)
75    );
76
77    // Generates: when() and and_then() methods that consume self
78    impl_box_consumer_methods!(
79        BoxBiConsumerOnce<T, U>,
80        BoxConditionalBiConsumerOnce,
81        BiConsumerOnce
82    );
83}
84
85impl<T, U> BiConsumerOnce<T, U> for BoxBiConsumerOnce<T, U> {
86    fn accept(self, first: &T, second: &U) {
87        (self.function)(first, second)
88    }
89
90    impl_box_once_conversions!(
91        BoxBiConsumerOnce<T, U>,
92        BiConsumerOnce,
93        FnOnce(&T, &U)
94    );
95}
96
97// Use macro to generate Debug and Display implementations
98impl_consumer_debug_display!(BoxBiConsumerOnce<T, U>);
99
100// =======================================================================
101// 3. Implement BiConsumerOnce trait for closures
102// =======================================================================
103
104// Implement BiConsumerOnce for all FnOnce(&T, &U) using macro
105impl_closure_once_trait!(
106    BiConsumerOnce<T, U>,
107    accept,
108    BoxBiConsumerOnce,
109    FnOnce(first: &T, second: &U)
110);