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