Skip to main content

qubit_function/consumers/
stateful_consumer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Consumer Types
10//!
11//! Provides implementations of consumer interfaces for executing operations
12//! that accept a single input parameter but return no result.
13//!
14//! It is similar to the `FnMut(&T)` trait in the standard library.
15//!
16//! This module provides a unified `Consumer` trait and three concrete
17//! implementations based on different ownership models:
18//!
19//! - **`BoxStatefulConsumer<T>`**: Box-based single ownership implementation for
20//!   one-time use scenarios
21//! - **`ArcStatefulConsumer<T>`**: Thread-safe shared ownership implementation
22//!   based on Arc<Mutex<>>
23//! - **`RcStatefulConsumer<T>`**: Single-threaded shared ownership implementation
24//!   based on Rc<RefCell<>>
25//!
26//! # Design Philosophy
27//!
28//! Consumer uses `FnMut(&T)` semantics, allowing modification of its own state
29//! but not the input value.
30//!
31//! Suitable for statistics, accumulation, event handling, and other scenarios.
32//!
33//! # Author
34//!
35//! Haixing Hu
36use std::cell::RefCell;
37use std::rc::Rc;
38use std::sync::Arc;
39
40use parking_lot::Mutex;
41
42use crate::consumers::consumer_once::BoxConsumerOnce;
43use crate::consumers::macros::{
44    impl_box_conditional_consumer,
45    impl_box_consumer_methods,
46    impl_conditional_consumer_clone,
47    impl_conditional_consumer_conversions,
48    impl_conditional_consumer_debug_display,
49    impl_consumer_clone,
50    impl_consumer_common_methods,
51    impl_consumer_debug_display,
52    impl_shared_conditional_consumer,
53    impl_shared_consumer_methods,
54};
55use crate::macros::{
56    impl_arc_conversions,
57    impl_box_conversions,
58    impl_closure_trait,
59    impl_rc_conversions,
60};
61use crate::predicates::predicate::{
62    ArcPredicate,
63    BoxPredicate,
64    Predicate,
65    RcPredicate,
66};
67
68// ============================================================================
69// 1. Consumer Trait - Unified Consumer Interface
70// ============================================================================
71
72/// Consumer trait - Unified consumer interface
73///
74/// Defines the core behavior of all consumer types. Similar to Java's
75/// `Consumer<T>` interface, executes operations that accept a value but return
76/// no result (side effects only).
77///
78/// It is similar to the `FnMut(&T)` trait in the standard library.
79///
80/// Consumer can modify its own state (such as accumulation, counting), but
81/// should not modify the consumed value itself.
82///
83/// # Automatic Implementation
84///
85/// - All closures implementing `FnMut(&T)`
86/// - `BoxStatefulConsumer<T>`, `ArcStatefulConsumer<T>`, `RcStatefulConsumer<T>`
87///
88/// # Features
89///
90/// - **Unified Interface**: All consumer types share the same `accept` method
91///   signature
92/// - **Automatic Implementation**: Closures automatically implement this trait
93///   with zero overhead
94/// - **Type Conversion**: Easy conversion between different ownership models
95/// - **Generic Programming**: Write functions that work with any consumer type
96///
97/// # Examples
98///
99/// ```rust
100/// use qubit_function::{Consumer, BoxStatefulConsumer, ArcStatefulConsumer};
101/// use std::sync::{Arc, Mutex};
102///
103/// fn apply_consumer<C: StatefulConsumer<i32>>(consumer: &mut C, value: &i32) {
104///     consumer.accept(value);
105/// }
106///
107/// // Works with any consumer type
108/// let log = Arc::new(Mutex::new(Vec::new()));
109/// let l = log.clone();
110/// let mut box_con = BoxStatefulConsumer::new(move |x: &i32| {
111///     l.lock().unwrap().push(*x);
112/// });
113/// apply_consumer(&mut box_con, &5);
114/// assert_eq!(*log.lock().unwrap(), vec![5]);
115/// ```
116///
117/// # Author
118///
119/// Haixing Hu
120pub trait StatefulConsumer<T> {
121    /// Execute consumption operation
122    ///
123    /// Performs an operation on the given reference. The operation typically
124    /// reads the input value or produces side effects, but does not modify the
125    /// input value itself. Can modify the consumer's own state.
126    ///
127    /// # Parameters
128    ///
129    /// * `value` - Reference to the value to be consumed
130    ///
131    /// # Examples
132    ///
133    /// ```rust
134    /// use qubit_function::{Consumer, BoxStatefulConsumer};
135    ///
136    /// let mut consumer = BoxStatefulConsumer::new(|x: &i32| println!("{}", x));
137    /// let value = 5;
138    /// consumer.accept(&value);
139    /// ```
140    fn accept(&mut self, value: &T);
141
142    /// Convert to BoxStatefulConsumer
143    ///
144    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
145    /// calling this method.
146    ///
147    /// Converts the current consumer to `BoxStatefulConsumer<T>`.
148    ///
149    /// # Ownership
150    ///
151    /// This method **consumes** the consumer (takes ownership of `self`).
152    /// After calling this method, the original consumer is no longer available.
153    ///
154    /// **Tip**: For cloneable consumers ([`ArcStatefulConsumer`], [`RcStatefulConsumer`]),
155    /// if you need to preserve the original object, you can call `.clone()`
156    /// first.
157    ///
158    /// # Return Value
159    ///
160    /// Returns the wrapped `BoxStatefulConsumer<T>`
161    ///
162    /// # Examples
163    ///
164    /// ```rust
165    /// use qubit_function::Consumer;
166    /// use std::sync::{Arc, Mutex};
167    ///
168    /// let log = Arc::new(Mutex::new(Vec::new()));
169    /// let l = log.clone();
170    /// let closure = move |x: &i32| {
171    ///     l.lock().unwrap().push(*x);
172    /// };
173    /// let mut box_consumer = closure.into_box();
174    /// box_consumer.accept(&5);
175    /// assert_eq!(*log.lock().unwrap(), vec![5]);
176    /// ```
177    fn into_box(self) -> BoxStatefulConsumer<T>
178    where
179        Self: Sized + 'static,
180    {
181        let mut consumer = self;
182        BoxStatefulConsumer::new(move |t| consumer.accept(t))
183    }
184
185    /// Convert to RcStatefulConsumer
186    ///
187    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
188    /// calling this method.
189    ///
190    /// # Return Value
191    ///
192    /// Returns the wrapped `RcStatefulConsumer<T>`
193    fn into_rc(self) -> RcStatefulConsumer<T>
194    where
195        Self: Sized + 'static,
196    {
197        let mut consumer = self;
198        RcStatefulConsumer::new(move |t| consumer.accept(t))
199    }
200
201    /// Convert to ArcStatefulConsumer
202    ///
203    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
204    /// calling this method.
205    ///
206    /// # Return Value
207    ///
208    /// Returns the wrapped `ArcStatefulConsumer<T>`
209    fn into_arc(self) -> ArcStatefulConsumer<T>
210    where
211        Self: Sized + Send + 'static,
212    {
213        let mut consumer = self;
214        ArcStatefulConsumer::new(move |t| consumer.accept(t))
215    }
216
217    /// Convert to closure
218    ///
219    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
220    /// calling this method.
221    ///
222    /// Converts the consumer to a closure that can be used directly in standard
223    /// library functions requiring `FnMut`.
224    ///
225    /// # Return Value
226    ///
227    /// Returns a closure implementing `FnMut(&T)`
228    ///
229    /// # Examples
230    ///
231    /// ```rust
232    /// use qubit_function::{Consumer, BoxStatefulConsumer};
233    /// use std::sync::{Arc, Mutex};
234    ///
235    /// let log = Arc::new(Mutex::new(Vec::new()));
236    /// let l = log.clone();
237    /// let consumer = BoxStatefulConsumer::new(move |x: &i32| {
238    ///     l.lock().unwrap().push(*x);
239    /// });
240    /// let mut func = consumer.into_fn();
241    /// func(&5);
242    /// assert_eq!(*log.lock().unwrap(), vec![5]);
243    /// ```
244    fn into_fn(self) -> impl FnMut(&T)
245    where
246        Self: Sized + 'static,
247    {
248        let mut consumer = self;
249        move |t| consumer.accept(t)
250    }
251
252    /// Convert to ConsumerOnce
253    ///
254    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after calling this method.
255    ///
256    /// Converts a reusable stateful consumer to a one-time consumer that consumes itself on use.
257    /// This enables passing `StatefulConsumer` to functions that require `ConsumerOnce`.
258    ///
259    /// # Returns
260    ///
261    /// Returns a `BoxConsumerOnce<T>`
262    ///
263    /// # Examples
264    ///
265    /// ```rust
266    ///
267    /// fn takes_once<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
268    ///     consumer.accept(value);
269    /// }
270    ///
271    /// let consumer = BoxStatefulConsumer::new(|x: &i32| println!("{}", x));
272    /// takes_once(consumer.into_once(), &5);
273    /// ```
274    fn into_once(self) -> BoxConsumerOnce<T>
275    where
276        Self: Sized + 'static,
277    {
278        BoxConsumerOnce::new(move |t| {
279            let mut consumer = self;
280            consumer.accept(t);
281        })
282    }
283
284    /// Convert to BoxStatefulConsumer
285    ///
286    /// **⚠️ Requires Clone**: The original consumer must implement Clone.
287    ///
288    /// Converts the current consumer to `BoxStatefulConsumer<T>` by cloning it first.
289    ///
290    /// # Ownership
291    ///
292    /// This method does **not consume** the consumer. It clones the consumer and
293    /// then converts the clone to `BoxStatefulConsumer<T>`. The original consumer remains
294    /// available after calling this method.
295    ///
296    /// # Return Value
297    ///
298    /// Returns the wrapped `BoxStatefulConsumer<T>` from the clone
299    ///
300    /// # Examples
301    ///
302    /// ```rust
303    /// use qubit_function::{Consumer, ArcStatefulConsumer};
304    /// use std::sync::{Arc, Mutex};
305    ///
306    /// let log = Arc::new(Mutex::new(Vec::new()));
307    /// let l = log.clone();
308    /// let consumer = ArcStatefulConsumer::new(move |x: &i32| {
309    ///     l.lock().unwrap().push(*x);
310    /// });
311    /// let mut box_consumer = consumer.to_box();
312    /// box_consumer.accept(&5);
313    /// assert_eq!(*log.lock().unwrap(), vec![5]);
314    /// // Original consumer still usable
315    /// consumer.accept(&3);
316    /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
317    /// ```
318    fn to_box(&self) -> BoxStatefulConsumer<T>
319    where
320        Self: Sized + Clone + 'static,
321    {
322        self.clone().into_box()
323    }
324
325    /// Convert to RcStatefulConsumer
326    ///
327    /// **⚠️ Requires Clone**: The original consumer must implement Clone.
328    ///
329    /// Converts the current consumer to `RcStatefulConsumer<T>` by cloning it first.
330    ///
331    /// # Ownership
332    ///
333    /// This method does **not consume** the consumer. It clones the consumer and
334    /// then converts the clone to `RcStatefulConsumer<T>`. The original consumer remains
335    /// available after calling this method.
336    ///
337    /// # Return Value
338    ///
339    /// Returns the wrapped `RcStatefulConsumer<T>` from the clone
340    ///
341    /// # Examples
342    ///
343    /// ```rust
344    /// use qubit_function::{Consumer, ArcStatefulConsumer};
345    /// use std::sync::{Arc, Mutex};
346    ///
347    /// let log = Arc::new(Mutex::new(Vec::new()));
348    /// let l = log.clone();
349    /// let consumer = ArcStatefulConsumer::new(move |x: &i32| {
350    ///     l.lock().unwrap().push(*x);
351    /// });
352    /// let mut rc_consumer = consumer.to_rc();
353    /// rc_consumer.accept(&5);
354    /// assert_eq!(*log.lock().unwrap(), vec![5]);
355    /// // Original consumer still usable
356    /// consumer.accept(&3);
357    /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
358    /// ```
359    fn to_rc(&self) -> RcStatefulConsumer<T>
360    where
361        Self: Sized + Clone + 'static,
362    {
363        self.clone().into_rc()
364    }
365
366    /// Convert to ArcStatefulConsumer
367    ///
368    /// **⚠️ Requires Clone + Send**: The original consumer must implement
369    /// Clone + Send.
370    ///
371    /// Converts the current consumer to `ArcStatefulConsumer<T>` by cloning it first.
372    ///
373    /// # Ownership
374    ///
375    /// This method does **not consume** the consumer. It clones the consumer and
376    /// then converts the clone to `ArcStatefulConsumer<T>`. The original consumer remains
377    /// available after calling this method.
378    ///
379    /// # Return Value
380    ///
381    /// Returns the wrapped `ArcStatefulConsumer<T>` from the clone
382    ///
383    /// # Examples
384    ///
385    /// ```rust
386    /// use qubit_function::{Consumer, RcStatefulConsumer};
387    /// use std::rc::Rc;
388    /// use std::cell::RefCell;
389    ///
390    /// let log = Rc::new(RefCell::new(Vec::new()));
391    /// let l = log.clone();
392    /// let consumer = RcStatefulConsumer::new(move |x: &i32| {
393    ///     l.borrow_mut().push(*x);
394    /// });
395    /// let mut arc_consumer = consumer.to_arc();
396    /// arc_consumer.accept(&5);
397    /// assert_eq!(*log.borrow(), vec![5]);
398    /// // Original consumer still usable
399    /// consumer.accept(&3);
400    /// assert_eq!(*log.borrow(), vec![5, 3]);
401    /// ```
402    fn to_arc(&self) -> ArcStatefulConsumer<T>
403    where
404        Self: Sized + Clone + Send + 'static,
405    {
406        self.clone().into_arc()
407    }
408
409    /// Convert to closure
410    ///
411    /// **⚠️ Requires Clone**: The original consumer must implement Clone.
412    ///
413    /// Converts the consumer to a closure that can be used directly in standard
414    /// library functions requiring `FnMut`.
415    ///
416    /// # Ownership
417    ///
418    /// This method does **not consume** the consumer. It clones the consumer and
419    /// then converts the clone to a closure. The original consumer remains
420    /// available after calling this method.
421    ///
422    /// # Return Value
423    ///
424    /// Returns a closure implementing `FnMut(&T)` from the clone
425    ///
426    /// # Examples
427    ///
428    /// ```rust
429    /// use qubit_function::{Consumer, BoxStatefulConsumer};
430    /// use std::sync::{Arc, Mutex};
431    ///
432    /// let log = Arc::new(Mutex::new(Vec::new()));
433    /// let l = log.clone();
434    /// let consumer = BoxStatefulConsumer::new(move |x: &i32| {
435    ///     l.lock().unwrap().push(*x);
436    /// });
437    /// let mut func = consumer.to_fn();
438    /// func(&5);
439    /// assert_eq!(*log.lock().unwrap(), vec![5]);
440    /// // Original consumer still usable
441    /// consumer.accept(&3);
442    /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
443    /// ```
444    fn to_fn(&self) -> impl FnMut(&T)
445    where
446        Self: Sized + Clone + 'static,
447    {
448        self.clone().into_fn()
449    }
450
451    /// Convert to ConsumerOnce without consuming self
452    ///
453    /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
454    /// Clones the current consumer and converts the clone to a one-time consumer.
455    ///
456    /// # Returns
457    ///
458    /// Returns a `BoxConsumerOnce<T>`
459    ///
460    /// # Examples
461    ///
462    /// ```rust
463    ///
464    /// fn takes_once<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
465    ///     consumer.accept(value);
466    /// }
467    ///
468    /// let consumer = BoxStatefulConsumer::new(|x: &i32| println!("{}", x));
469    /// takes_once(consumer.to_once(), &5);
470    /// ```
471    fn to_once(&self) -> BoxConsumerOnce<T>
472    where
473        Self: Clone + 'static,
474    {
475        self.clone().into_once()
476    }
477}
478
479// ============================================================================
480// 2. BoxStatefulConsumer - Single Ownership Implementation
481// ============================================================================
482
483/// BoxStatefulConsumer struct
484///
485/// Consumer implementation based on `Box<dyn FnMut(&T)>` for single ownership
486/// scenarios. When sharing is not needed, this is the simplest and most
487/// efficient consumer type.
488///
489/// # Features
490///
491/// - **Single Ownership**: Not cloneable, transfers ownership when used
492/// - **Zero Overhead**: No reference counting or lock overhead
493/// - **Mutable State**: Can modify captured environment through `FnMut`
494/// - **Builder Pattern**: Method chaining naturally consumes `self`
495///
496/// # Use Cases
497///
498/// Choose `BoxStatefulConsumer` when:
499/// - Consumer is used only once or in a linear flow
500/// - Building pipelines where ownership flows naturally
501/// - No need to share consumers across contexts
502/// - Performance critical and cannot accept sharing overhead
503///
504/// # Performance
505///
506/// `BoxStatefulConsumer` has the best performance among the three consumer types:
507/// - No reference counting overhead
508/// - No lock acquisition or runtime borrowing checks
509/// - Direct function calls through vtable
510/// - Minimal memory footprint (single pointer)
511///
512/// # Examples
513///
514/// ```rust
515/// use qubit_function::{Consumer, BoxStatefulConsumer};
516/// use std::sync::{Arc, Mutex};
517///
518/// let log = Arc::new(Mutex::new(Vec::new()));
519/// let l = log.clone();
520/// let mut consumer = BoxStatefulConsumer::new(move |x: &i32| {
521///     l.lock().unwrap().push(*x);
522/// });
523/// consumer.accept(&5);
524/// assert_eq!(*log.lock().unwrap(), vec![5]);
525/// ```
526///
527/// # Author
528///
529/// Haixing Hu
530pub struct BoxStatefulConsumer<T> {
531    function: Box<dyn FnMut(&T)>,
532    name: Option<String>,
533}
534
535impl<T> BoxStatefulConsumer<T> {
536    // Generates: new(), new_with_name(), name(), set_name(), noop()
537    impl_consumer_common_methods!(BoxStatefulConsumer<T>, (FnMut(&T) + 'static), |f| Box::new(
538        f
539    ));
540
541    // Generates: when() and and_then() methods that consume self
542    impl_box_consumer_methods!(
543        BoxStatefulConsumer<T>,
544        BoxConditionalStatefulConsumer,
545        StatefulConsumer
546    );
547}
548
549impl<T> StatefulConsumer<T> for BoxStatefulConsumer<T> {
550    fn accept(&mut self, value: &T) {
551        (self.function)(value)
552    }
553
554    // Generates: into_box(), into_rc(), into_fn(), into_once()
555    impl_box_conversions!(
556        BoxStatefulConsumer<T>,
557        RcStatefulConsumer,
558        FnMut(&T),
559        BoxConsumerOnce
560    );
561}
562
563// Use macro to generate Debug and Display implementations
564impl_consumer_debug_display!(BoxStatefulConsumer<T>);
565
566// ============================================================================
567// 3. RcStatefulConsumer - Single-Threaded Shared Ownership Implementation
568// ============================================================================
569
570/// RcStatefulConsumer struct
571///
572/// Consumer implementation based on `Rc<RefCell<dyn FnMut(&T)>>` for
573/// single-threaded shared ownership scenarios. This consumer provides the
574/// benefits of shared ownership without the overhead of thread safety.
575///
576/// # Features
577///
578/// - **Shared Ownership**: Cloneable through `Rc`, allowing multiple owners
579/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
580/// - **Interior Mutability**: Uses `RefCell` for runtime borrowing checks
581/// - **No Lock Overhead**: More efficient than `ArcStatefulConsumer` for single-threaded
582///   use
583/// - **Non-Consuming API**: `and_then` borrows `&self`, original object remains
584///   usable
585///
586/// # Use Cases
587///
588/// Choose `RcStatefulConsumer` when:
589/// - Need to share consumers within a single thread
590/// - Thread safety is not needed
591/// - Performance is important (avoid lock overhead)
592/// - UI event handling in single-threaded frameworks
593/// - Building complex single-threaded state machines
594///
595/// # Performance Considerations
596///
597/// `RcStatefulConsumer` performs better than `ArcStatefulConsumer` in single-threaded scenarios:
598/// - **Non-Atomic Counting**: clone/drop is cheaper than `Arc`
599/// - **No Lock Overhead**: `RefCell` uses runtime checks, no locks
600/// - **Better Cache Locality**: No atomic operations means better CPU cache
601///   behavior
602///
603/// But still has slight overhead compared to `BoxStatefulConsumer`:
604/// - **Reference Counting**: Non-atomic but still exists
605/// - **Runtime Borrowing Checks**: `RefCell` checks at runtime
606///
607/// # Safety
608///
609/// `RcStatefulConsumer` is not thread-safe and does not implement `Send` or `Sync`.
610/// Attempting to send it to another thread will result in a compilation error.
611/// For thread-safe sharing, use `ArcStatefulConsumer` instead.
612///
613/// # Examples
614///
615/// ```rust
616/// use qubit_function::{Consumer, RcStatefulConsumer};
617/// use std::rc::Rc;
618/// use std::cell::RefCell;
619///
620/// let log = Rc::new(RefCell::new(Vec::new()));
621/// let l = log.clone();
622/// let mut consumer = RcStatefulConsumer::new(move |x: &i32| {
623///     l.borrow_mut().push(*x * 2);
624/// });
625/// let mut clone = consumer.clone();
626///
627/// consumer.accept(&5);
628/// assert_eq!(*log.borrow(), vec![10]);
629/// ```
630///
631/// # Author
632///
633/// Haixing Hu
634pub struct RcStatefulConsumer<T> {
635    function: Rc<RefCell<dyn FnMut(&T)>>,
636    name: Option<String>,
637}
638
639impl<T> RcStatefulConsumer<T> {
640    // Generates: new(), new_with_name(), name(), set_name(), noop()
641    impl_consumer_common_methods!(RcStatefulConsumer<T>, (FnMut(&T) + 'static), |f| Rc::new(
642        RefCell::new(f)
643    ));
644
645    // Generates: when() and and_then() methods that borrow &self (Rc can clone)
646    impl_shared_consumer_methods!(
647        RcStatefulConsumer<T>,
648        RcConditionalStatefulConsumer,
649        into_rc,
650        StatefulConsumer,
651        'static
652    );
653}
654
655impl<T> StatefulConsumer<T> for RcStatefulConsumer<T> {
656    fn accept(&mut self, value: &T) {
657        (self.function.borrow_mut())(value)
658    }
659
660    // Use macro to implement conversion methods
661    impl_rc_conversions!(
662        RcStatefulConsumer<T>,
663        BoxStatefulConsumer,
664        BoxConsumerOnce,
665        FnMut(t: &T)
666    );
667}
668
669// Use macro to generate Clone implementation
670impl_consumer_clone!(RcStatefulConsumer<T>);
671
672// Use macro to generate Debug and Display implementations
673impl_consumer_debug_display!(RcStatefulConsumer<T>);
674
675// ============================================================================
676// 4. ArcStatefulConsumer - Thread-Safe Shared Ownership Implementation
677// ============================================================================
678
679/// ArcStatefulConsumer struct
680///
681/// Consumer implementation based on `Arc<Mutex<dyn FnMut(&T) + Send>>` for
682/// thread-safe shared ownership scenarios. This consumer can be safely cloned
683/// and shared across multiple threads.
684///
685/// # Features
686///
687/// - **Shared Ownership**: Cloneable through `Arc`, allowing multiple owners
688/// - **Thread Safety**: Implements `Send + Sync`, safe for concurrent use
689/// - **Interior Mutability**: Uses `Mutex` for safe mutable access
690/// - **Non-Consuming API**: `and_then` borrows `&self`, original object remains
691///   usable
692/// - **Cross-Thread Sharing**: Can be sent to other threads and used
693///
694/// # Use Cases
695///
696/// Choose `ArcStatefulConsumer` when:
697/// - Need to share consumers across multiple threads
698/// - Concurrent task processing (e.g., thread pools)
699/// - Using the same consumer in multiple places simultaneously
700/// - Need thread safety (Send + Sync)
701///
702/// # Performance Considerations
703///
704/// `ArcStatefulConsumer` has some performance overhead compared to `BoxStatefulConsumer`:
705/// - **Reference Counting**: Atomic operations on clone/drop
706/// - **Mutex Locking**: Each `accept` call requires lock acquisition
707/// - **Lock Contention**: High concurrency may cause contention
708///
709/// These overheads are necessary for safe concurrent access. If thread safety
710/// is not needed, consider using `RcStatefulConsumer` for less single-threaded sharing
711/// overhead.
712///
713/// # Examples
714///
715/// ```rust
716/// use qubit_function::{Consumer, ArcStatefulConsumer};
717/// use std::sync::{Arc, Mutex};
718///
719/// let log = Arc::new(Mutex::new(Vec::new()));
720/// let l = log.clone();
721/// let mut consumer = ArcStatefulConsumer::new(move |x: &i32| {
722///     l.lock().unwrap().push(*x * 2);
723/// });
724/// let mut clone = consumer.clone();
725///
726/// consumer.accept(&5);
727/// assert_eq!(*log.lock().unwrap(), vec![10]);
728/// ```
729///
730/// # Author
731///
732/// Haixing Hu
733pub struct ArcStatefulConsumer<T> {
734    function: Arc<Mutex<dyn FnMut(&T) + Send>>,
735    name: Option<String>,
736}
737
738impl<T> ArcStatefulConsumer<T> {
739    // Generates: new(), new_with_name(), name(), set_name(), noop()
740    impl_consumer_common_methods!(ArcStatefulConsumer<T>, (FnMut(&T) + Send + 'static), |f| {
741        Arc::new(Mutex::new(f))
742    });
743
744    // Generates: when() and and_then() methods that borrow &self (Arc can clone)
745    impl_shared_consumer_methods!(
746        ArcStatefulConsumer<T>,
747        ArcConditionalStatefulConsumer,
748        into_arc,
749        StatefulConsumer,
750        Send + Sync + 'static
751    );
752}
753
754impl<T> StatefulConsumer<T> for ArcStatefulConsumer<T> {
755    fn accept(&mut self, value: &T) {
756        (self.function.lock())(value)
757    }
758
759    // Use macro to implement conversion methods
760    impl_arc_conversions!(
761        ArcStatefulConsumer<T>,
762        BoxStatefulConsumer,
763        RcStatefulConsumer,
764        BoxConsumerOnce,
765        FnMut(t: &T)
766    );
767}
768
769// Use macro to generate Clone implementation
770impl_consumer_clone!(ArcStatefulConsumer<T>);
771
772// Use macro to generate Debug and Display implementations
773impl_consumer_debug_display!(ArcStatefulConsumer<T>);
774
775// ============================================================================
776// 5. Implement Consumer trait for closures
777// ============================================================================
778
779// Implement Consumer for all FnMut(&T)
780impl_closure_trait!(
781    StatefulConsumer<T>,
782    accept,
783    BoxConsumerOnce,
784    FnMut(value: &T)
785);
786
787// ============================================================================
788// 6. Extension methods for closures
789// ============================================================================
790
791/// Extension trait providing consumer composition methods for closures
792///
793/// Provides `and_then` and other composition methods for all closures
794/// implementing `FnMut(&T)`, allowing direct method chaining on closures
795/// without explicit wrapper types.
796///
797/// # Design Philosophy
798///
799/// This trait allows closures to be naturally composed using method syntax,
800/// similar to iterator combinators. Composition methods consume the closure and
801/// return `BoxStatefulConsumer<T>`, which can continue chaining.
802///
803/// # Features
804///
805/// - **Natural Syntax**: Direct method chaining on closures
806/// - **Returns BoxStatefulConsumer**: Composition results in `BoxStatefulConsumer<T>`, can
807///   continue chaining
808/// - **Zero Cost**: No overhead when composing closures
809/// - **Automatic Implementation**: All `FnMut(&T)` closures automatically get
810///   these methods
811///
812/// # Examples
813///
814/// ```rust
815/// use qubit_function::{Consumer, FnStatefulConsumerOps};
816/// use std::sync::{Arc, Mutex};
817///
818/// let log = Arc::new(Mutex::new(Vec::new()));
819/// let l1 = log.clone();
820/// let l2 = log.clone();
821/// let mut chained = (move |x: &i32| {
822///     l1.lock().unwrap().push(*x * 2);
823/// }).and_then(move |x: &i32| {
824///     l2.lock().unwrap().push(*x + 10);
825/// });
826/// chained.accept(&5);
827/// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
828/// // (5 * 2), (5 + 10)
829/// ```
830///
831/// # Author
832///
833/// Haixing Hu
834pub trait FnStatefulConsumerOps<T>: FnMut(&T) + Sized {
835    /// Sequentially chain another consumer
836    ///
837    /// Returns a new consumer that executes the current operation first, then the
838    /// next operation. Consumes the current closure and returns `BoxStatefulConsumer<T>`.
839    ///
840    /// # Type Parameters
841    ///
842    /// * `C` - Type of the next consumer
843    ///
844    /// # Parameters
845    ///
846    /// * `next` - Consumer to execute after the current operation. **Note: This
847    ///   parameter is passed by value and will transfer ownership.** If you need
848    ///   to preserve the original consumer, clone it first (if it implements
849    ///   `Clone`). Can be:
850    ///   - A closure: `|x: &T|`
851    ///   - A `BoxStatefulConsumer<T>`
852    ///   - An `RcStatefulConsumer<T>`
853    ///   - An `ArcStatefulConsumer<T>`
854    ///   - Any type implementing `Consumer<T>`
855    ///
856    /// # Return Value
857    ///
858    /// Returns a combined `BoxStatefulConsumer<T>`
859    ///
860    /// # Examples
861    ///
862    /// ## Direct value passing (ownership transfer)
863    ///
864    /// ```rust
865    /// use qubit_function::{Consumer, FnStatefulConsumerOps, BoxStatefulConsumer};
866    /// use std::sync::{Arc, Mutex};
867    ///
868    /// let log = Arc::new(Mutex::new(Vec::new()));
869    /// let l1 = log.clone();
870    /// let l2 = log.clone();
871    /// let second = BoxStatefulConsumer::new(move |x: &i32| {
872    ///     l2.lock().unwrap().push(*x + 10);
873    /// });
874    ///
875    /// // second is moved here
876    /// let mut chained = (move |x: &i32| {
877    ///     l1.lock().unwrap().push(*x * 2);
878    /// }).and_then(second);
879    ///
880    /// chained.accept(&5);
881    /// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
882    /// // second.accept(&3); // Would not compile - moved
883    /// ```
884    ///
885    /// ## Preserving original with clone
886    ///
887    /// ```rust
888    /// use qubit_function::{Consumer, FnStatefulConsumerOps, BoxStatefulConsumer};
889    /// use std::sync::{Arc, Mutex};
890    ///
891    /// let log = Arc::new(Mutex::new(Vec::new()));
892    /// let l1 = log.clone();
893    /// let l2 = log.clone();
894    /// let second = BoxStatefulConsumer::new(move |x: &i32| {
895    ///     l2.lock().unwrap().push(*x + 10);
896    /// });
897    ///
898    /// // Clone to preserve original
899    /// let mut chained = (move |x: &i32| {
900    ///     l1.lock().unwrap().push(*x * 2);
901    /// }).and_then(second.clone());
902    ///
903    /// chained.accept(&5);
904    /// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
905    ///
906    /// // Original still usable
907    /// second.accept(&3);
908    /// assert_eq!(*log.lock().unwrap(), vec![10, 15, 13]);
909    /// ```
910    fn and_then<C>(self, next: C) -> BoxStatefulConsumer<T>
911    where
912        Self: 'static,
913        C: StatefulConsumer<T> + 'static,
914        T: 'static,
915    {
916        let mut first = self;
917        let mut second = next;
918        BoxStatefulConsumer::new(move |t| {
919            first(t);
920            second.accept(t);
921        })
922    }
923}
924
925/// Implement FnStatefulConsumerOps for all closure types
926impl<T, F> FnStatefulConsumerOps<T> for F where F: FnMut(&T) {}
927
928// ============================================================================
929// 7. BoxConditionalStatefulConsumer - Box-based Conditional Consumer
930// ============================================================================
931
932/// BoxConditionalStatefulConsumer struct
933///
934/// A conditional consumer that only executes when a predicate is satisfied.
935/// Uses `BoxStatefulConsumer` and `BoxPredicate` for single ownership semantics.
936///
937/// This type is typically created by calling `BoxStatefulConsumer::when()` and is
938/// designed to work with the `or_else()` method to create if-then-else logic.
939///
940/// # Features
941///
942/// - **Single Ownership**: Not cloneable, consumes `self` on use
943/// - **Conditional Execution**: Only consumes when predicate returns `true`
944/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
945/// - **Implements Consumer**: Can be used anywhere a `Consumer` is expected
946///
947/// # Examples
948///
949/// ## Basic Conditional Execution
950///
951/// ```rust
952/// use qubit_function::{Consumer, BoxStatefulConsumer};
953/// use std::sync::{Arc, Mutex};
954///
955/// let log = Arc::new(Mutex::new(Vec::new()));
956/// let l = log.clone();
957/// let consumer = BoxStatefulConsumer::new(move |x: &i32| {
958///     l.lock().unwrap().push(*x);
959/// });
960/// let mut conditional = consumer.when(|x: &i32| *x > 0);
961///
962/// conditional.accept(&5);
963/// assert_eq!(*log.lock().unwrap(), vec![5]); // Executed
964///
965/// conditional.accept(&-5);
966/// assert_eq!(*log.lock().unwrap(), vec![5]); // Not executed
967/// ```
968///
969/// ## With or_else Branch
970///
971/// ```rust
972/// use qubit_function::{Consumer, BoxStatefulConsumer};
973/// use std::sync::{Arc, Mutex};
974///
975/// let log = Arc::new(Mutex::new(Vec::new()));
976/// let l1 = log.clone();
977/// let l2 = log.clone();
978/// let mut consumer = BoxStatefulConsumer::new(move |x: &i32| {
979///     l1.lock().unwrap().push(*x);
980/// })
981/// .when(|x: &i32| *x > 0)
982/// .or_else(move |x: &i32| {
983///     l2.lock().unwrap().push(-*x);
984/// });
985///
986/// consumer.accept(&5);
987/// assert_eq!(*log.lock().unwrap(), vec![5]); // when branch executed
988///
989/// consumer.accept(&-5);
990/// assert_eq!(*log.lock().unwrap(), vec![5, 5]); // or_else branch executed
991/// ```
992///
993/// # Author
994///
995/// Haixing Hu
996pub struct BoxConditionalStatefulConsumer<T> {
997    consumer: BoxStatefulConsumer<T>,
998    predicate: BoxPredicate<T>,
999}
1000
1001// Use macro to generate and_then and or_else methods
1002impl_box_conditional_consumer!(
1003    BoxConditionalStatefulConsumer<T>,
1004    BoxStatefulConsumer,
1005    StatefulConsumer
1006);
1007
1008impl<T> StatefulConsumer<T> for BoxConditionalStatefulConsumer<T> {
1009    fn accept(&mut self, value: &T) {
1010        if self.predicate.test(value) {
1011            self.consumer.accept(value);
1012        }
1013    }
1014
1015    // Generates: into_box(), into_rc(), into_fn()
1016    impl_conditional_consumer_conversions!(BoxStatefulConsumer<T>, RcStatefulConsumer, FnMut);
1017}
1018
1019// Use macro to generate Debug and Display implementations
1020impl_conditional_consumer_debug_display!(BoxConditionalStatefulConsumer<T>);
1021
1022// ============================================================================
1023// 8. ArcConditionalStatefulConsumer - Arc-based Conditional Consumer
1024// ============================================================================
1025
1026/// ArcConditionalStatefulConsumer struct
1027///
1028/// A thread-safe conditional consumer that only executes when a predicate is
1029/// satisfied. Uses `ArcStatefulConsumer` and `ArcPredicate` for shared ownership across
1030/// threads.
1031///
1032/// This type is typically created by calling `ArcStatefulConsumer::when()` and is
1033/// designed to work with the `or_else()` method to create if-then-else logic.
1034///
1035/// # Features
1036///
1037/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
1038/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
1039/// - **Conditional Execution**: Only consumes when predicate returns `true`
1040/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
1041///
1042/// # Examples
1043///
1044/// ```rust
1045/// use qubit_function::{Consumer, ArcStatefulConsumer};
1046/// use std::sync::{Arc, Mutex};
1047///
1048/// let log = Arc::new(Mutex::new(Vec::new()));
1049/// let l = log.clone();
1050/// let conditional = ArcStatefulConsumer::new(move |x: &i32| {
1051///     l.lock().unwrap().push(*x);
1052/// })
1053/// .when(|x: &i32| *x > 0);
1054///
1055/// let conditional_clone = conditional.clone();
1056///
1057/// let mut value = 5;
1058/// let mut m = conditional;
1059/// m.accept(&value);
1060/// assert_eq!(*log.lock().unwrap(), vec![5]);
1061/// ```
1062///
1063/// # Author
1064///
1065/// Haixing Hu
1066pub struct ArcConditionalStatefulConsumer<T> {
1067    consumer: ArcStatefulConsumer<T>,
1068    predicate: ArcPredicate<T>,
1069}
1070
1071// Use macro to generate and_then and or_else methods
1072impl_shared_conditional_consumer!(
1073    ArcConditionalStatefulConsumer<T>,
1074    ArcStatefulConsumer,
1075    StatefulConsumer,
1076    into_arc,
1077    Send + Sync + 'static
1078);
1079
1080impl<T> StatefulConsumer<T> for ArcConditionalStatefulConsumer<T> {
1081    fn accept(&mut self, value: &T) {
1082        if self.predicate.test(value) {
1083            self.consumer.accept(value);
1084        }
1085    }
1086
1087    // Generates: into_box(), into_rc(), into_fn()
1088    impl_conditional_consumer_conversions!(BoxStatefulConsumer<T>, RcStatefulConsumer, FnMut);
1089}
1090
1091// Use macro to generate Clone implementation
1092impl_conditional_consumer_clone!(ArcConditionalStatefulConsumer<T>);
1093
1094// Use macro to generate Debug and Display implementations
1095impl_conditional_consumer_debug_display!(ArcConditionalStatefulConsumer<T>);
1096
1097// ============================================================================
1098// 9. RcConditionalStatefulConsumer - Rc-based Conditional Consumer
1099// ============================================================================
1100
1101/// RcConditionalStatefulConsumer struct
1102///
1103/// A single-threaded conditional consumer that only executes when a predicate is
1104/// satisfied. Uses `RcStatefulConsumer` and `RcPredicate` for shared ownership within a
1105/// single thread.
1106///
1107/// This type is typically created by calling `RcStatefulConsumer::when()` and is
1108/// designed to work with the `or_else()` method to create if-then-else logic.
1109///
1110/// # Features
1111///
1112/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
1113/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
1114/// - **Conditional Execution**: Only consumes when predicate returns `true`
1115/// - **No Lock Overhead**: More efficient than `ArcConditionalStatefulConsumer`
1116///
1117/// # Examples
1118///
1119/// ```rust
1120/// use qubit_function::{Consumer, RcStatefulConsumer};
1121/// use std::rc::Rc;
1122/// use std::cell::RefCell;
1123///
1124/// let log = Rc::new(RefCell::new(Vec::new()));
1125/// let l = log.clone();
1126/// let conditional = RcStatefulConsumer::new(move |x: &i32| {
1127///     l.borrow_mut().push(*x);
1128/// })
1129/// .when(|x: &i32| *x > 0);
1130///
1131/// let conditional_clone = conditional.clone();
1132///
1133/// let mut value = 5;
1134/// let mut m = conditional;
1135/// m.accept(&value);
1136/// assert_eq!(*log.borrow(), vec![5]);
1137/// ```
1138///
1139/// # Author
1140///
1141/// Haixing Hu
1142pub struct RcConditionalStatefulConsumer<T> {
1143    consumer: RcStatefulConsumer<T>,
1144    predicate: RcPredicate<T>,
1145}
1146
1147// Use macro to generate and_then and or_else methods
1148impl_shared_conditional_consumer!(
1149    RcConditionalStatefulConsumer<T>,
1150    RcStatefulConsumer,
1151    StatefulConsumer,
1152    into_rc,
1153    'static
1154);
1155
1156impl<T> StatefulConsumer<T> for RcConditionalStatefulConsumer<T> {
1157    fn accept(&mut self, value: &T) {
1158        if self.predicate.test(value) {
1159            self.consumer.accept(value);
1160        }
1161    }
1162
1163    // Generates: into_box(), into_rc(), into_fn()
1164    impl_conditional_consumer_conversions!(BoxStatefulConsumer<T>, RcStatefulConsumer, FnMut);
1165}
1166
1167// Use macro to generate Clone implementation
1168impl_conditional_consumer_clone!(RcConditionalStatefulConsumer<T>);
1169
1170// Use macro to generate Debug and Display implementations
1171impl_conditional_consumer_debug_display!(RcConditionalStatefulConsumer<T>);