qubit_function/consumers/consumer/arc_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 `ArcConditionalConsumer` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// ============================================================================
16// 9. ArcConditionalConsumer - Arc-based Conditional Consumer
17// ============================================================================
18
19/// ArcConditionalConsumer struct
20///
21/// A conditional non-mutating consumer that only executes when a predicate is satisfied.
22/// Uses `ArcConsumer` and `ArcPredicate` for thread-safe shared ownership semantics.
23///
24/// This type is typically created by calling `ArcConsumer::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 `Arc`, allows multiple owners
30/// - **Thread Safe**: Implements `Send + Sync`, can be safely used concurrently
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, ArcConsumer};
42///
43/// let consumer = ArcConsumer::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, ArcConsumer};
56///
57/// let consumer = ArcConsumer::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 ArcConditionalConsumer<T> {
73 pub(super) consumer: ArcConsumer<T>,
74 pub(super) predicate: ArcPredicate<T>,
75}
76
77// Use macro to generate conditional consumer implementations
78impl_shared_conditional_consumer!(
79 ArcConditionalConsumer<T>,
80 ArcConsumer,
81 Consumer,
82 into_arc,
83 Send + Sync + 'static
84);
85
86// Hand-written Consumer trait implementation
87impl<T> Consumer<T> for ArcConditionalConsumer<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!(ArcConditionalConsumer<T>);
100
101// Use macro to generate Debug and Display implementations
102impl_conditional_consumer_debug_display!(ArcConditionalConsumer<T>);