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