Skip to main content

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