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