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