Skip to main content

qubit_function/consumers/bi_consumer/
box_conditional_bi_consumer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `BoxConditionalBiConsumer` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// =======================================================================
16// 7. BoxConditionalBiConsumer - Box-based Conditional BiConsumer
17// =======================================================================
18
19/// BoxConditionalBiConsumer struct
20///
21/// A conditional non-mutating bi-consumer that only executes when a predicate is satisfied.
22/// Uses `BoxBiConsumer` and `BoxBiPredicate` for single ownership semantics.
23///
24/// This type is typically created by calling `BoxBiConsumer::when()` and is
25/// designed to work with the `or_else()` method to create if-then-else logic.
26///
27/// # Features
28///
29/// - **Single Ownership**: Not cloneable, consumes `self` on use
30/// - **Conditional Execution**: Only consumes when predicate returns `true`
31/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
32/// - **Implements BiConsumer**: Can be used anywhere a `BiConsumer` is expected
33/// - **Non-mutating**: Neither modifies itself nor input values
34///
35/// # Examples
36///
37/// ## Basic Conditional Execution
38///
39/// ```rust
40/// use qubit_function::{BiConsumer, BoxBiConsumer};
41///
42/// let consumer = BoxBiConsumer::new(|x: &i32, y: &i32| {
43///     println!("Both positive: {} + {} = {}", x, y, x + y);
44/// });
45/// let conditional = consumer.when(|x: &i32, y: &i32| *x > 0 && *y > 0);
46///
47/// conditional.accept(&5, &3);  // Prints: Both positive: 5 + 3 = 8
48/// conditional.accept(&-5, &3); // Does nothing
49/// ```
50///
51/// ## With or_else Branch
52///
53/// ```rust
54/// use qubit_function::{BiConsumer, BoxBiConsumer};
55///
56/// let consumer = BoxBiConsumer::new(|x: &i32, y: &i32| {
57///     println!("Both positive: {} + {} = {}", x, y, x + y);
58/// })
59/// .when(|x: &i32, y: &i32| *x > 0 && *y > 0)
60/// .or_else(|x: &i32, y: &i32| {
61///     println!("Not both positive: {} and {}", x, y);
62/// });
63///
64/// consumer.accept(&5, &3);  // Prints: Both positive: 5 + 3 = 8
65/// consumer.accept(&-5, &3); // Prints: Not both positive: -5 and 3
66/// ```
67///
68/// # Author
69///
70/// Haixing Hu
71pub struct BoxConditionalBiConsumer<T, U> {
72    pub(super) consumer: BoxBiConsumer<T, U>,
73    pub(super) predicate: BoxBiPredicate<T, U>,
74}
75
76// Use macro to generate conditional bi-consumer implementations
77impl_box_conditional_consumer!(
78    BoxConditionalBiConsumer<T, U>,
79    BoxBiConsumer,
80    BiConsumer
81);
82
83// Hand-written BiConsumer trait implementation
84impl<T, U> BiConsumer<T, U> for BoxConditionalBiConsumer<T, U> {
85    fn accept(&self, first: &T, second: &U) {
86        if self.predicate.test(first, second) {
87            self.consumer.accept(first, second);
88        }
89    }
90
91    // Generates: into_box(), into_rc(), into_fn()
92    impl_conditional_consumer_conversions!(
93        BoxBiConsumer<T, U>,
94        RcBiConsumer,
95        Fn
96    );
97}
98
99// Use macro to generate Debug and Display implementations
100impl_conditional_consumer_debug_display!(BoxConditionalBiConsumer<T, U>);