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}