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>);