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}