Skip to main content

qubit_function/consumers/consumer_once/
box_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 `BoxConsumerOnce` public type.
12
13use super::{
14    BoxConditionalConsumerOnce,
15    ConsumerOnce,
16    Predicate,
17    impl_box_consumer_methods,
18    impl_box_once_conversions,
19    impl_closure_once_trait,
20    impl_consumer_common_methods,
21    impl_consumer_debug_display,
22};
23
24// ============================================================================
25// 2. BoxConsumerOnce - Single Ownership Implementation
26// ============================================================================
27
28/// BoxConsumerOnce struct
29///
30/// One-time consumer implementation based on `Box<dyn FnOnce(&T)>` for single ownership scenarios.
31/// This is the simplest consumer type for truly one-time use.
32///
33/// # Features
34///
35/// - **Single Ownership**: Not cloneable, transfers ownership on use
36/// - **Zero Overhead**: No reference counting or lock overhead
37/// - **One-time Use**: Consumes self on first call
38/// - **Builder Pattern**: Method chaining naturally consumes `self`
39///
40/// # Use Cases
41///
42/// Choose `BoxConsumerOnce` when:
43/// - Consumer is truly used only once
44/// - Building pipelines where ownership flows naturally
45/// - Consumer captures values that should be consumed
46/// - Performance critical and cannot accept shared overhead
47///
48/// # Performance
49///
50/// `BoxConsumerOnce` has the best performance:
51/// - No reference counting overhead
52/// - No lock acquisition or runtime borrow checking
53/// - Direct function call through vtable
54/// - Minimal memory footprint (single pointer)
55///
56/// # Examples
57///
58/// ```rust
59/// use qubit_function::{ConsumerOnce, BoxConsumerOnce};
60///
61/// let consumer = BoxConsumerOnce::new(|x: &i32| {
62///     println!("Value: {}", x);
63/// });
64/// consumer.accept(&5);
65/// ```
66///
67pub struct BoxConsumerOnce<T> {
68    pub(super) function: Box<dyn FnOnce(&T)>,
69    pub(super) name: Option<String>,
70}
71
72// All methods require T: 'static because Box<dyn FnOnce(&T)> requires it
73impl<T> BoxConsumerOnce<T> {
74    // Generates: new(), new_with_name(), name(), set_name(), noop()
75    impl_consumer_common_methods!(BoxConsumerOnce<T>, (FnOnce(&T) + 'static), |f| Box::new(f));
76
77    // Generates: when() and and_then() methods that consume self
78    impl_box_consumer_methods!(BoxConsumerOnce<T>, BoxConditionalConsumerOnce, ConsumerOnce);
79}
80
81impl<T> ConsumerOnce<T> for BoxConsumerOnce<T> {
82    fn accept(self, value: &T) {
83        (self.function)(value)
84    }
85
86    impl_box_once_conversions!(BoxConsumerOnce<T>, ConsumerOnce, FnOnce(&T));
87}
88
89// Use macro to generate Debug and Display implementations
90impl_consumer_debug_display!(BoxConsumerOnce<T>);
91
92// ============================================================================
93// 3. Implement ConsumerOnce trait for closures
94// ============================================================================
95
96// Implement ConsumerOnce for all FnOnce(&T) using macro
97impl_closure_once_trait!(
98    ConsumerOnce<T>,
99    accept,
100    BoxConsumerOnce,
101    FnOnce(value: &T)
102);