Skip to main content

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