Skip to main content

qubit_function/consumers/stateful_consumer/
box_stateful_consumer.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 `BoxStatefulConsumer` public type.
12
13#![allow(unused_imports)]
14
15use super::*;
16
17// ============================================================================
18// 2. BoxStatefulConsumer - Single Ownership Implementation
19// ============================================================================
20
21/// BoxStatefulConsumer struct
22///
23/// Consumer implementation based on `Box<dyn FnMut(&T)>` for single ownership
24/// scenarios. When sharing is not needed, this is the simplest and most
25/// efficient consumer type.
26///
27/// # Features
28///
29/// - **Single Ownership**: Not cloneable, transfers ownership when used
30/// - **Zero Overhead**: No reference counting or lock overhead
31/// - **Mutable State**: Can modify captured environment through `FnMut`
32/// - **Builder Pattern**: Method chaining naturally consumes `self`
33///
34/// # Use Cases
35///
36/// Choose `BoxStatefulConsumer` when:
37/// - Consumer is used only once or in a linear flow
38/// - Building pipelines where ownership flows naturally
39/// - No need to share consumers across contexts
40/// - Performance critical and cannot accept sharing overhead
41///
42/// # Performance
43///
44/// `BoxStatefulConsumer` has the best performance among the three consumer types:
45/// - No reference counting overhead
46/// - No lock acquisition or runtime borrowing checks
47/// - Direct function calls through vtable
48/// - Minimal memory footprint (single pointer)
49///
50/// # Examples
51///
52/// ```rust
53/// use qubit_function::{Consumer, StatefulConsumer, BoxStatefulConsumer};
54/// use std::sync::{Arc, Mutex};
55///
56/// let log = Arc::new(Mutex::new(Vec::new()));
57/// let l = log.clone();
58/// let mut consumer = BoxStatefulConsumer::new(move |x: &i32| {
59///     l.lock().unwrap().push(*x);
60/// });
61/// consumer.accept(&5);
62/// assert_eq!(*log.lock().unwrap(), vec![5]);
63/// ```
64///
65pub struct BoxStatefulConsumer<T> {
66    pub(super) function: Box<dyn FnMut(&T)>,
67    pub(super) name: Option<String>,
68}
69
70impl<T> BoxStatefulConsumer<T> {
71    // Generates: new(), new_with_name(), name(), set_name(), noop()
72    impl_consumer_common_methods!(BoxStatefulConsumer<T>, (FnMut(&T) + 'static), |f| Box::new(
73        f
74    ));
75
76    // Generates: when() and and_then() methods that consume self
77    impl_box_consumer_methods!(
78        BoxStatefulConsumer<T>,
79        BoxConditionalStatefulConsumer,
80        StatefulConsumer
81    );
82}
83
84impl<T> StatefulConsumer<T> for BoxStatefulConsumer<T> {
85    fn accept(&mut self, value: &T) {
86        (self.function)(value)
87    }
88
89    // Generates: into_box(), into_rc(), into_fn(), into_once()
90    impl_box_conversions!(
91        BoxStatefulConsumer<T>,
92        RcStatefulConsumer,
93        FnMut(&T),
94        BoxConsumerOnce
95    );
96}
97
98// Use macro to generate Debug and Display implementations
99impl_consumer_debug_display!(BoxStatefulConsumer<T>);