qubit_function/consumers/consumer/box_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 `BoxConsumer` public type.
12
13use super::{
14 BoxConditionalConsumer,
15 BoxConsumerOnce,
16 Consumer,
17 Predicate,
18 RcConsumer,
19 impl_box_consumer_methods,
20 impl_box_conversions,
21 impl_consumer_common_methods,
22 impl_consumer_debug_display,
23};
24
25// ============================================================================
26// 2. BoxConsumer - Single Ownership Implementation
27// ============================================================================
28
29/// BoxConsumer struct
30///
31/// Non-mutating consumer implementation based on `Box<dyn Fn(&T)>` for single
32/// ownership scenarios.
33///
34/// # Features
35///
36/// - **Single Ownership**: Not cloneable, transfers ownership when used
37/// - **Zero Overhead**: No reference counting or lock overhead
38/// - **Shared-reference API**: Invoked through `&self` and shared input
39/// references
40/// - **No Wrapper Interior Mutability**: No need for Mutex or RefCell in the
41/// wrapper
42///
43/// # Use Cases
44///
45/// Choose `BoxConsumer` when:
46/// - Non-mutating consumer is used once or in a linear flow
47/// - No need to share consumer across contexts
48/// - Pure observation operations, such as logging
49///
50/// # Examples
51///
52/// ```rust
53/// use qubit_function::{Consumer, BoxConsumer};
54///
55/// let consumer = BoxConsumer::new(|x: &i32| {
56/// println!("Observed value: {}", x);
57/// });
58/// consumer.accept(&5);
59/// ```
60///
61pub struct BoxConsumer<T> {
62 pub(super) function: Box<dyn Fn(&T)>,
63 pub(super) name: Option<String>,
64}
65
66impl<T> BoxConsumer<T> {
67 // Generates: new(), new_with_name(), name(), set_name(), noop()
68 impl_consumer_common_methods!(BoxConsumer<T>, (Fn(&T) + 'static), |f| Box::new(f));
69
70 // Generates: when() and and_then() methods that consume self
71 impl_box_consumer_methods!(BoxConsumer<T>, BoxConditionalConsumer, Consumer);
72}
73
74impl<T> Consumer<T> for BoxConsumer<T> {
75 fn accept(&self, value: &T) {
76 (self.function)(value)
77 }
78
79 // Generates: into_box(), into_rc(), into_fn(), into_once()
80 impl_box_conversions!(BoxConsumer<T>, RcConsumer, Fn(&T), BoxConsumerOnce);
81}
82
83// Use macro to generate Debug and Display implementations
84impl_consumer_debug_display!(BoxConsumer<T>);