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
68mod box_stateful_consumer;
69pub use box_stateful_consumer::BoxStatefulConsumer;
70mod rc_stateful_consumer;
71pub use rc_stateful_consumer::RcStatefulConsumer;
72mod arc_stateful_consumer;
73pub use arc_stateful_consumer::ArcStatefulConsumer;
74mod fn_stateful_consumer_ops;
75pub use fn_stateful_consumer_ops::FnStatefulConsumerOps;
76mod box_conditional_stateful_consumer;
77pub use box_conditional_stateful_consumer::BoxConditionalStatefulConsumer;
78mod arc_conditional_stateful_consumer;
79pub use arc_conditional_stateful_consumer::ArcConditionalStatefulConsumer;
80mod rc_conditional_stateful_consumer;
81pub use rc_conditional_stateful_consumer::RcConditionalStatefulConsumer;
82
83// ============================================================================
84// 1. Consumer Trait - Unified Consumer Interface
85// ============================================================================
86
87/// Consumer trait - Unified consumer interface
88///
89/// Defines the core behavior of all consumer types. Similar to Java's
90/// `Consumer<T>` interface, executes operations that accept a value but return
91/// no result (side effects only).
92///
93/// It is similar to the `FnMut(&T)` trait in the standard library.
94///
95/// Consumer can modify its own state (such as accumulation, counting), but
96/// should not modify the consumed value itself.
97///
98/// # Automatic Implementation
99///
100/// - All closures implementing `FnMut(&T)`
101/// - `BoxStatefulConsumer<T>`, `ArcStatefulConsumer<T>`, `RcStatefulConsumer<T>`
102///
103/// # Features
104///
105/// - **Unified Interface**: All consumer types share the same `accept` method
106///   signature
107/// - **Automatic Implementation**: Closures automatically implement this trait
108///   with zero overhead
109/// - **Type Conversion**: Easy conversion between different ownership models
110/// - **Generic Programming**: Write functions that work with any consumer type
111///
112/// # Examples
113///
114/// ```rust
115/// use qubit_function::{Consumer, StatefulConsumer, BoxStatefulConsumer, ArcStatefulConsumer};
116/// use std::sync::{Arc, Mutex};
117///
118/// fn apply_consumer<C: StatefulConsumer<i32>>(consumer: &mut C, value: &i32) {
119///     consumer.accept(value);
120/// }
121///
122/// // Works with any consumer type
123/// let log = Arc::new(Mutex::new(Vec::new()));
124/// let l = log.clone();
125/// let mut box_con = BoxStatefulConsumer::new(move |x: &i32| {
126///     l.lock().unwrap().push(*x);
127/// });
128/// apply_consumer(&mut box_con, &5);
129/// assert_eq!(*log.lock().unwrap(), vec![5]);
130/// ```
131///
132/// # Author
133///
134/// Haixing Hu
135pub trait StatefulConsumer<T> {
136    /// Execute consumption operation
137    ///
138    /// Performs an operation on the given reference. The operation typically
139    /// reads the input value or produces side effects, but does not modify the
140    /// input value itself. Can modify the consumer's own state.
141    ///
142    /// # Parameters
143    ///
144    /// * `value` - Reference to the value to be consumed
145    ///
146    /// # Examples
147    ///
148    /// ```rust
149    /// use qubit_function::{Consumer, StatefulConsumer, BoxStatefulConsumer};
150    ///
151    /// let mut consumer = BoxStatefulConsumer::new(|x: &i32| println!("{}", x));
152    /// let value = 5;
153    /// consumer.accept(&value);
154    /// ```
155    fn accept(&mut self, value: &T);
156
157    /// Convert to BoxStatefulConsumer
158    ///
159    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
160    /// calling this method.
161    ///
162    /// Converts the current consumer to `BoxStatefulConsumer<T>`.
163    ///
164    /// # Ownership
165    ///
166    /// This method **consumes** the consumer (takes ownership of `self`).
167    /// After calling this method, the original consumer is no longer available.
168    ///
169    /// **Tip**: For cloneable consumers ([`ArcStatefulConsumer`], [`RcStatefulConsumer`]),
170    /// if you need to preserve the original object, you can call `.clone()`
171    /// first.
172    ///
173    /// # Return Value
174    ///
175    /// Returns the wrapped `BoxStatefulConsumer<T>`
176    ///
177    /// # Examples
178    ///
179    /// ```rust
180    /// use qubit_function::Consumer;
181    /// use std::sync::{Arc, Mutex};
182    ///
183    /// let log = Arc::new(Mutex::new(Vec::new()));
184    /// let l = log.clone();
185    /// let closure = move |x: &i32| {
186    ///     l.lock().unwrap().push(*x);
187    /// };
188    /// let mut box_consumer = closure.into_box();
189    /// box_consumer.accept(&5);
190    /// assert_eq!(*log.lock().unwrap(), vec![5]);
191    /// ```
192    fn into_box(self) -> BoxStatefulConsumer<T>
193    where
194        Self: Sized + 'static,
195    {
196        let mut consumer = self;
197        BoxStatefulConsumer::new(move |t| consumer.accept(t))
198    }
199
200    /// Convert to RcStatefulConsumer
201    ///
202    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
203    /// calling this method.
204    ///
205    /// # Return Value
206    ///
207    /// Returns the wrapped `RcStatefulConsumer<T>`
208    fn into_rc(self) -> RcStatefulConsumer<T>
209    where
210        Self: Sized + 'static,
211    {
212        let mut consumer = self;
213        RcStatefulConsumer::new(move |t| consumer.accept(t))
214    }
215
216    /// Convert to ArcStatefulConsumer
217    ///
218    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
219    /// calling this method.
220    ///
221    /// # Return Value
222    ///
223    /// Returns the wrapped `ArcStatefulConsumer<T>`
224    fn into_arc(self) -> ArcStatefulConsumer<T>
225    where
226        Self: Sized + Send + 'static,
227    {
228        let mut consumer = self;
229        ArcStatefulConsumer::new(move |t| consumer.accept(t))
230    }
231
232    /// Convert to closure
233    ///
234    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
235    /// calling this method.
236    ///
237    /// Converts the consumer to a closure that can be used directly in standard
238    /// library functions requiring `FnMut`.
239    ///
240    /// # Return Value
241    ///
242    /// Returns a closure implementing `FnMut(&T)`
243    ///
244    /// # Examples
245    ///
246    /// ```rust
247    /// use qubit_function::{Consumer, StatefulConsumer, RcStatefulConsumer};
248    /// use std::sync::{Arc, Mutex};
249    ///
250    /// let log = Arc::new(Mutex::new(Vec::new()));
251    /// let l = log.clone();
252    /// let mut consumer = RcStatefulConsumer::new(move |x: &i32| {
253    ///     l.lock().unwrap().push(*x);
254    /// });
255    /// let mut func = consumer.into_fn();
256    /// func(&5);
257    /// assert_eq!(*log.lock().unwrap(), vec![5]);
258    /// ```
259    fn into_fn(self) -> impl FnMut(&T)
260    where
261        Self: Sized + 'static,
262    {
263        let mut consumer = self;
264        move |t| consumer.accept(t)
265    }
266
267    /// Convert to ConsumerOnce
268    ///
269    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after calling this method.
270    ///
271    /// Converts a reusable stateful consumer to a one-time consumer that consumes itself on use.
272    /// This enables passing `StatefulConsumer` to functions that require `ConsumerOnce`.
273    ///
274    /// # Returns
275    ///
276    /// Returns a `BoxConsumerOnce<T>`
277    ///
278    /// # Examples
279    ///
280    /// ```rust
281    /// use qubit_function::{Consumer, ConsumerOnce, StatefulConsumer, BoxStatefulConsumer};
282    ///
283    /// fn takes_once<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
284    ///     consumer.accept(value);
285    /// }
286    ///
287    /// let consumer = BoxStatefulConsumer::new(|x: &i32| println!("{}", x));
288    /// takes_once(consumer.into_once(), &5);
289    /// ```
290    fn into_once(self) -> BoxConsumerOnce<T>
291    where
292        Self: Sized + 'static,
293    {
294        BoxConsumerOnce::new(move |t| {
295            let mut consumer = self;
296            consumer.accept(t);
297        })
298    }
299
300    /// Convert to BoxStatefulConsumer
301    ///
302    /// **⚠️ Requires Clone**: The original consumer must implement Clone.
303    ///
304    /// Converts the current consumer to `BoxStatefulConsumer<T>` by cloning it first.
305    ///
306    /// # Ownership
307    ///
308    /// This method does **not consume** the consumer. It clones the consumer and
309    /// then converts the clone to `BoxStatefulConsumer<T>`. The original consumer remains
310    /// available after calling this method.
311    ///
312    /// # Return Value
313    ///
314    /// Returns the wrapped `BoxStatefulConsumer<T>` from the clone
315    ///
316    /// # Examples
317    ///
318    /// ```rust
319    /// use qubit_function::{Consumer, StatefulConsumer, ArcStatefulConsumer};
320    /// use std::sync::{Arc, Mutex};
321    ///
322    /// let log = Arc::new(Mutex::new(Vec::new()));
323    /// let l = log.clone();
324    /// let mut consumer = ArcStatefulConsumer::new(move |x: &i32| {
325    ///     l.lock().unwrap().push(*x);
326    /// });
327    /// let mut box_consumer = consumer.to_box();
328    /// box_consumer.accept(&5);
329    /// assert_eq!(*log.lock().unwrap(), vec![5]);
330    /// // Original consumer still usable
331    /// consumer.accept(&3);
332    /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
333    /// ```
334    fn to_box(&self) -> BoxStatefulConsumer<T>
335    where
336        Self: Sized + Clone + 'static,
337    {
338        self.clone().into_box()
339    }
340
341    /// Convert to RcStatefulConsumer
342    ///
343    /// **⚠️ Requires Clone**: The original consumer must implement Clone.
344    ///
345    /// Converts the current consumer to `RcStatefulConsumer<T>` by cloning it first.
346    ///
347    /// # Ownership
348    ///
349    /// This method does **not consume** the consumer. It clones the consumer and
350    /// then converts the clone to `RcStatefulConsumer<T>`. The original consumer remains
351    /// available after calling this method.
352    ///
353    /// # Return Value
354    ///
355    /// Returns the wrapped `RcStatefulConsumer<T>` from the clone
356    ///
357    /// # Examples
358    ///
359    /// ```rust
360    /// use qubit_function::{Consumer, StatefulConsumer, ArcStatefulConsumer};
361    /// use std::sync::{Arc, Mutex};
362    ///
363    /// let log = Arc::new(Mutex::new(Vec::new()));
364    /// let l = log.clone();
365    /// let mut consumer = ArcStatefulConsumer::new(move |x: &i32| {
366    ///     l.lock().unwrap().push(*x);
367    /// });
368    /// let mut rc_consumer = consumer.to_rc();
369    /// rc_consumer.accept(&5);
370    /// assert_eq!(*log.lock().unwrap(), vec![5]);
371    /// // Original consumer still usable
372    /// consumer.accept(&3);
373    /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
374    /// ```
375    fn to_rc(&self) -> RcStatefulConsumer<T>
376    where
377        Self: Sized + Clone + 'static,
378    {
379        self.clone().into_rc()
380    }
381
382    /// Convert to ArcStatefulConsumer
383    ///
384    /// **⚠️ Requires Clone + Send**: The original consumer must implement
385    /// Clone + Send.
386    ///
387    /// Converts the current consumer to `ArcStatefulConsumer<T>` by cloning it first.
388    ///
389    /// # Ownership
390    ///
391    /// This method does **not consume** the consumer. It clones the consumer and
392    /// then converts the clone to `ArcStatefulConsumer<T>`. The original consumer remains
393    /// available after calling this method.
394    ///
395    /// # Return Value
396    ///
397    /// Returns the wrapped `ArcStatefulConsumer<T>` from the clone
398    ///
399    /// # Examples
400    ///
401    /// ```rust
402    /// use qubit_function::{Consumer, StatefulConsumer, ArcStatefulConsumer};
403    /// use std::sync::{Arc, Mutex};
404    ///
405    /// let log = Arc::new(Mutex::new(Vec::new()));
406    /// let l = log.clone();
407    /// let mut consumer = ArcStatefulConsumer::new(move |x: &i32| {
408    ///     l.lock().unwrap().push(*x);
409    /// });
410    /// let mut arc_consumer = consumer.to_arc();
411    /// arc_consumer.accept(&5);
412    /// assert_eq!(*log.lock().unwrap(), vec![5]);
413    /// // Original consumer still usable
414    /// consumer.accept(&3);
415    /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
416    /// ```
417    fn to_arc(&self) -> ArcStatefulConsumer<T>
418    where
419        Self: Sized + Clone + Send + 'static,
420    {
421        self.clone().into_arc()
422    }
423
424    /// Convert to closure
425    ///
426    /// **⚠️ Requires Clone**: The original consumer must implement Clone.
427    ///
428    /// Converts the consumer to a closure that can be used directly in standard
429    /// library functions requiring `FnMut`.
430    ///
431    /// # Ownership
432    ///
433    /// This method does **not consume** the consumer. It clones the consumer and
434    /// then converts the clone to a closure. The original consumer remains
435    /// available after calling this method.
436    ///
437    /// # Return Value
438    ///
439    /// Returns a closure implementing `FnMut(&T)` from the clone
440    ///
441    /// # Examples
442    ///
443    /// ```rust
444    /// use qubit_function::{Consumer, StatefulConsumer, RcStatefulConsumer};
445    /// use std::sync::{Arc, Mutex};
446    ///
447    /// let log = Arc::new(Mutex::new(Vec::new()));
448    /// let l = log.clone();
449    /// let mut consumer = RcStatefulConsumer::new(move |x: &i32| {
450    ///     l.lock().unwrap().push(*x);
451    /// });
452    /// {
453    ///     let mut func = consumer.to_fn();
454    ///     func(&5);
455    /// }
456    /// assert_eq!(*log.lock().unwrap(), vec![5]);
457    /// // Original consumer still usable
458    /// consumer.accept(&3);
459    /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
460    /// ```
461    fn to_fn(&self) -> impl FnMut(&T)
462    where
463        Self: Sized + Clone + 'static,
464    {
465        self.clone().into_fn()
466    }
467
468    /// Convert to ConsumerOnce without consuming self
469    ///
470    /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
471    /// Clones the current consumer and converts the clone to a one-time consumer.
472    ///
473    /// # Returns
474    ///
475    /// Returns a `BoxConsumerOnce<T>`
476    ///
477    /// # Examples
478    ///
479    /// ```rust
480    /// use qubit_function::{Consumer, ConsumerOnce, StatefulConsumer, RcStatefulConsumer};
481    ///
482    /// fn takes_once<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
483    ///     consumer.accept(value);
484    /// }
485    ///
486    /// let consumer = RcStatefulConsumer::new(|x: &i32| println!("{}", x));
487    /// takes_once(consumer.to_once(), &5);
488    /// ```
489    fn to_once(&self) -> BoxConsumerOnce<T>
490    where
491        Self: Clone + 'static,
492    {
493        self.clone().into_once()
494    }
495}