Skip to main content

qubit_function/consumers/stateful_bi_consumer/
arc_conditional_stateful_bi_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 `ArcConditionalStatefulBiConsumer` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// =======================================================================
16// 8. ArcConditionalStatefulBiConsumer - Arc-based Conditional BiConsumer
17// =======================================================================
18
19/// ArcConditionalStatefulBiConsumer struct
20///
21/// A thread-safe conditional bi-consumer that only executes when a predicate is
22/// satisfied. Uses `ArcStatefulBiConsumer` and `ArcBiPredicate` for shared ownership across
23/// threads.
24///
25/// This type is typically created by calling `ArcStatefulBiConsumer::when()` and is
26/// designed to work with the `or_else()` method to create if-then-else logic.
27///
28/// # Features
29///
30/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
31/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
32/// - **Conditional Execution**: Only consumes when predicate returns `true`
33/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
34///
35/// # Examples
36///
37/// ```rust
38/// use qubit_function::{BiConsumer, ArcStatefulBiConsumer, StatefulBiConsumer};
39/// use std::sync::{Arc, Mutex};
40///
41/// let log = Arc::new(Mutex::new(Vec::new()));
42/// let l = log.clone();
43/// let conditional = ArcStatefulBiConsumer::new(move |x: &i32, y: &i32| {
44///     l.lock().unwrap().push(*x + *y);
45/// }).when(|x: &i32, y: &i32| *x > 0 && *y > 0);
46///
47/// let conditional_clone = conditional.clone();
48///
49/// let mut value = 5;
50/// let mut m = conditional;
51/// m.accept(&value, &3);
52/// assert_eq!(*log.lock().unwrap(), vec![8]);
53/// ```
54///
55/// # Author
56///
57/// Haixing Hu
58pub struct ArcConditionalStatefulBiConsumer<T, U> {
59    pub(super) consumer: ArcStatefulBiConsumer<T, U>,
60    pub(super) predicate: ArcBiPredicate<T, U>,
61}
62
63// Use macro to generate and_then and or_else methods
64impl_shared_conditional_consumer!(
65    ArcConditionalStatefulBiConsumer<T, U>,
66    ArcStatefulBiConsumer,
67    StatefulBiConsumer,
68    into_arc,
69    Send + Sync + 'static
70);
71
72impl<T, U> StatefulBiConsumer<T, U> for ArcConditionalStatefulBiConsumer<T, U> {
73    fn accept(&mut self, first: &T, second: &U) {
74        if self.predicate.test(first, second) {
75            self.consumer.accept(first, second);
76        }
77    }
78
79    // Generates: into_box(), into_rc(), into_fn()
80    impl_conditional_consumer_conversions!(
81        BoxStatefulBiConsumer<T, U>,
82        RcStatefulBiConsumer,
83        FnMut
84    );
85}
86
87// Use macro to generate Clone implementation
88impl_conditional_consumer_clone!(ArcConditionalStatefulBiConsumer<T, U>);
89
90// Use macro to generate Debug and Display implementations
91impl_conditional_consumer_debug_display!(ArcConditionalStatefulBiConsumer<T, U>);