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