Skip to main content

qubit_function/consumers/consumer/
box_conditional_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 `BoxConditionalConsumer` public type.
12
13#![allow(unused_imports)]
14
15use super::*;
16
17// ============================================================================
18// 7. BoxConditionalConsumer - Box-based Conditional Consumer
19// ============================================================================
20
21/// BoxConditionalConsumer struct
22///
23/// A conditional non-mutating consumer that only executes when a predicate is satisfied.
24/// Uses `BoxConsumer` and `BoxPredicate` for single ownership semantics.
25///
26/// This type is typically created by calling `BoxConsumer::when()` and is
27/// designed to work with the `or_else()` method to create if-then-else logic.
28///
29/// # Features
30///
31/// - **Single Ownership**: Not cloneable, consumes `self` on use
32/// - **Conditional Execution**: Only consumes when predicate returns `true`
33/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
34/// - **Implements Consumer**: Can be used anywhere a `Consumer` is expected
35/// - **Non-mutating**: Neither modifies itself nor input values
36///
37/// # Examples
38///
39/// ## Basic Conditional Execution
40///
41/// ```rust
42/// use qubit_function::{Consumer, BoxConsumer};
43///
44/// let consumer = BoxConsumer::new(|x: &i32| {
45///     println!("Positive: {}", x);
46/// });
47/// let conditional = consumer.when(|x: &i32| *x > 0);
48///
49/// conditional.accept(&5);  // Prints: Positive: 5
50/// conditional.accept(&-5); // Does nothing
51/// ```
52///
53/// ## With or_else Branch
54///
55/// ```rust
56/// use qubit_function::{Consumer, BoxConsumer};
57///
58/// let consumer = BoxConsumer::new(|x: &i32| {
59///     println!("Positive: {}", x);
60/// })
61/// .when(|x: &i32| *x > 0)
62/// .or_else(|x: &i32| {
63///     println!("Non-positive: {}", x);
64/// });
65///
66/// consumer.accept(&5);  // Prints: Positive: 5
67/// consumer.accept(&-5); // Prints: Non-positive: -5
68/// ```
69///
70pub struct BoxConditionalConsumer<T> {
71    pub(super) consumer: BoxConsumer<T>,
72    pub(super) predicate: BoxPredicate<T>,
73}
74
75// Use macro to generate conditional consumer implementations
76impl_box_conditional_consumer!(BoxConditionalConsumer<T>, BoxConsumer, Consumer);
77
78// Consumer trait implementation
79impl<T> Consumer<T> for BoxConditionalConsumer<T> {
80    fn accept(&self, value: &T) {
81        if self.predicate.test(value) {
82            self.consumer.accept(value);
83        }
84    }
85
86    // Generates: into_box(), into_rc(), into_fn()
87    impl_conditional_consumer_conversions!(BoxConsumer<T>, RcConsumer, Fn);
88}
89
90// Use macro to generate Debug and Display implementations
91impl_conditional_consumer_debug_display!(BoxConditionalConsumer<T>);