Skip to main content

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