prism3_function/consumer.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025.
4 * 3-Prism 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//! This module provides a unified `Consumer` trait and three concrete
15//! implementations based on different ownership models:
16//!
17//! - **`BoxConsumer<T>`**: Box-based single ownership implementation for
18//! one-time use scenarios
19//! - **`ArcConsumer<T>`**: Thread-safe shared ownership implementation
20//! based on Arc<Mutex<>>
21//! - **`RcConsumer<T>`**: Single-threaded shared ownership implementation
22//! based on Rc<RefCell<>>
23//!
24//! # Design Philosophy
25//!
26//! Consumer uses `FnMut(&T)` semantics, allowing modification of its own state
27//! but not the input value. Suitable for statistics, accumulation, event
28//! handling, and other scenarios.
29//!
30//! # Author
31//!
32//! Hu Haixing
33
34use std::cell::RefCell;
35use std::fmt;
36use std::rc::Rc;
37use std::sync::{Arc, Mutex};
38
39use crate::predicate::{ArcPredicate, BoxPredicate, Predicate, RcPredicate};
40
41/// Type alias for consumer function to simplify complex types.
42///
43/// This type alias represents a mutable function that takes a reference and
44/// returns nothing. It is used to reduce type complexity in struct definitions.
45type ConsumerFn<T> = dyn FnMut(&T);
46
47/// Type alias for thread-safe consumer function to simplify complex types.
48///
49/// This type alias represents a mutable function that takes a reference and
50/// returns nothing, with Send bound for thread-safe usage. It is used to
51/// reduce type complexity in Arc-based struct definitions.
52type SendConsumerFn<T> = dyn FnMut(&T) + Send;
53
54// ============================================================================
55// 1. Consumer Trait - Unified Consumer Interface
56// ============================================================================
57
58/// Consumer trait - Unified consumer interface
59///
60/// Defines the core behavior of all consumer types. Similar to Java's
61/// `Consumer<T>` interface, executes operations that accept a value but return
62/// no result (side effects only).
63///
64/// Consumer can modify its own state (such as accumulation, counting), but
65/// should not modify the consumed value itself.
66///
67/// # Automatic Implementation
68///
69/// - All closures implementing `FnMut(&T)`
70/// - `BoxConsumer<T>`, `ArcConsumer<T>`, `RcConsumer<T>`
71///
72/// # Features
73///
74/// - **Unified Interface**: All consumer types share the same `accept` method
75/// signature
76/// - **Automatic Implementation**: Closures automatically implement this trait
77/// with zero overhead
78/// - **Type Conversion**: Easy conversion between different ownership models
79/// - **Generic Programming**: Write functions that work with any consumer type
80///
81/// # Examples
82///
83/// ```rust
84/// use prism3_function::{Consumer, BoxConsumer, ArcConsumer};
85/// use std::sync::{Arc, Mutex};
86///
87/// fn apply_consumer<C: Consumer<i32>>(consumer: &mut C, value: &i32) {
88/// consumer.accept(value);
89/// }
90///
91/// // Works with any consumer type
92/// let log = Arc::new(Mutex::new(Vec::new()));
93/// let l = log.clone();
94/// let mut box_con = BoxConsumer::new(move |x: &i32| {
95/// l.lock().unwrap().push(*x);
96/// });
97/// apply_consumer(&mut box_con, &5);
98/// assert_eq!(*log.lock().unwrap(), vec![5]);
99/// ```
100///
101/// # Author
102///
103/// Hu Haixing
104pub trait Consumer<T> {
105 /// Execute consumption operation
106 ///
107 /// Performs an operation on the given reference. The operation typically
108 /// reads the input value or produces side effects, but does not modify the
109 /// input value itself. Can modify the consumer's own state.
110 ///
111 /// # Parameters
112 ///
113 /// * `value` - Reference to the value to be consumed
114 ///
115 /// # Examples
116 ///
117 /// ```rust
118 /// use prism3_function::{Consumer, BoxConsumer};
119 ///
120 /// let mut consumer = BoxConsumer::new(|x: &i32| println!("{}", x));
121 /// let value = 5;
122 /// consumer.accept(&value);
123 /// ```
124 fn accept(&mut self, value: &T);
125
126 /// Convert to BoxConsumer
127 ///
128 /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
129 /// calling this method.
130 ///
131 /// Converts the current consumer to `BoxConsumer<T>`.
132 ///
133 /// # Ownership
134 ///
135 /// This method **consumes** the consumer (takes ownership of `self`).
136 /// After calling this method, the original consumer is no longer available.
137 ///
138 /// **Tip**: For cloneable consumers ([`ArcConsumer`], [`RcConsumer`]),
139 /// if you need to preserve the original object, you can call `.clone()`
140 /// first.
141 ///
142 /// # Return Value
143 ///
144 /// Returns the wrapped `BoxConsumer<T>`
145 ///
146 /// # Examples
147 ///
148 /// ```rust
149 /// use prism3_function::Consumer;
150 /// use std::sync::{Arc, Mutex};
151 ///
152 /// let log = Arc::new(Mutex::new(Vec::new()));
153 /// let l = log.clone();
154 /// let closure = move |x: &i32| {
155 /// l.lock().unwrap().push(*x);
156 /// };
157 /// let mut box_consumer = closure.into_box();
158 /// box_consumer.accept(&5);
159 /// assert_eq!(*log.lock().unwrap(), vec![5]);
160 /// ```
161 fn into_box(self) -> BoxConsumer<T>
162 where
163 Self: Sized + 'static,
164 T: 'static,
165 {
166 let mut consumer = self;
167 BoxConsumer::new(move |t| consumer.accept(t))
168 }
169
170 /// Convert to RcConsumer
171 ///
172 /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
173 /// calling this method.
174 ///
175 /// # Return Value
176 ///
177 /// Returns the wrapped `RcConsumer<T>`
178 fn into_rc(self) -> RcConsumer<T>
179 where
180 Self: Sized + 'static,
181 T: 'static,
182 {
183 let mut consumer = self;
184 RcConsumer::new(move |t| consumer.accept(t))
185 }
186
187 /// Convert to ArcConsumer
188 ///
189 /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
190 /// calling this method.
191 ///
192 /// # Return Value
193 ///
194 /// Returns the wrapped `ArcConsumer<T>`
195 fn into_arc(self) -> ArcConsumer<T>
196 where
197 Self: Sized + Send + 'static,
198 T: Send + 'static,
199 {
200 let mut consumer = self;
201 ArcConsumer::new(move |t| consumer.accept(t))
202 }
203
204 /// Convert to closure
205 ///
206 /// **⚠️ Consumes `self`**: The original consumer will be unavailable after
207 /// calling this method.
208 ///
209 /// Converts the consumer to a closure that can be used directly in standard
210 /// library functions requiring `FnMut`.
211 ///
212 /// # Return Value
213 ///
214 /// Returns a closure implementing `FnMut(&T)`
215 ///
216 /// # Examples
217 ///
218 /// ```rust
219 /// use prism3_function::{Consumer, BoxConsumer};
220 /// use std::sync::{Arc, Mutex};
221 ///
222 /// let log = Arc::new(Mutex::new(Vec::new()));
223 /// let l = log.clone();
224 /// let consumer = BoxConsumer::new(move |x: &i32| {
225 /// l.lock().unwrap().push(*x);
226 /// });
227 /// let mut func = consumer.into_fn();
228 /// func(&5);
229 /// assert_eq!(*log.lock().unwrap(), vec![5]);
230 /// ```
231 fn into_fn(self) -> impl FnMut(&T)
232 where
233 Self: Sized + 'static,
234 T: 'static,
235 {
236 let mut consumer = self;
237 move |t| consumer.accept(t)
238 }
239
240 /// Convert to BoxConsumer
241 ///
242 /// **⚠️ Requires Clone**: The original consumer must implement Clone.
243 ///
244 /// Converts the current consumer to `BoxConsumer<T>` by cloning it first.
245 ///
246 /// # Ownership
247 ///
248 /// This method does **not consume** the consumer. It clones the consumer and
249 /// then converts the clone to `BoxConsumer<T>`. The original consumer remains
250 /// available after calling this method.
251 ///
252 /// # Return Value
253 ///
254 /// Returns the wrapped `BoxConsumer<T>` from the clone
255 ///
256 /// # Examples
257 ///
258 /// ```rust
259 /// use prism3_function::{Consumer, ArcConsumer};
260 /// use std::sync::{Arc, Mutex};
261 ///
262 /// let log = Arc::new(Mutex::new(Vec::new()));
263 /// let l = log.clone();
264 /// let consumer = ArcConsumer::new(move |x: &i32| {
265 /// l.lock().unwrap().push(*x);
266 /// });
267 /// let mut box_consumer = consumer.to_box();
268 /// box_consumer.accept(&5);
269 /// assert_eq!(*log.lock().unwrap(), vec![5]);
270 /// // Original consumer still usable
271 /// consumer.accept(&3);
272 /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
273 /// ```
274 fn to_box(&self) -> BoxConsumer<T>
275 where
276 Self: Sized + Clone + 'static,
277 T: 'static,
278 {
279 self.clone().into_box()
280 }
281
282 /// Convert to RcConsumer
283 ///
284 /// **⚠️ Requires Clone**: The original consumer must implement Clone.
285 ///
286 /// Converts the current consumer to `RcConsumer<T>` by cloning it first.
287 ///
288 /// # Ownership
289 ///
290 /// This method does **not consume** the consumer. It clones the consumer and
291 /// then converts the clone to `RcConsumer<T>`. The original consumer remains
292 /// available after calling this method.
293 ///
294 /// # Return Value
295 ///
296 /// Returns the wrapped `RcConsumer<T>` from the clone
297 ///
298 /// # Examples
299 ///
300 /// ```rust
301 /// use prism3_function::{Consumer, ArcConsumer};
302 /// use std::sync::{Arc, Mutex};
303 ///
304 /// let log = Arc::new(Mutex::new(Vec::new()));
305 /// let l = log.clone();
306 /// let consumer = ArcConsumer::new(move |x: &i32| {
307 /// l.lock().unwrap().push(*x);
308 /// });
309 /// let mut rc_consumer = consumer.to_rc();
310 /// rc_consumer.accept(&5);
311 /// assert_eq!(*log.lock().unwrap(), vec![5]);
312 /// // Original consumer still usable
313 /// consumer.accept(&3);
314 /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
315 /// ```
316 fn to_rc(&self) -> RcConsumer<T>
317 where
318 Self: Sized + Clone + 'static,
319 T: 'static,
320 {
321 self.clone().into_rc()
322 }
323
324 /// Convert to ArcConsumer
325 ///
326 /// **⚠️ Requires Clone + Send**: The original consumer must implement
327 /// Clone + Send.
328 ///
329 /// Converts the current consumer to `ArcConsumer<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 `ArcConsumer<T>`. The original consumer remains
335 /// available after calling this method.
336 ///
337 /// # Return Value
338 ///
339 /// Returns the wrapped `ArcConsumer<T>` from the clone
340 ///
341 /// # Examples
342 ///
343 /// ```rust
344 /// use prism3_function::{Consumer, RcConsumer};
345 /// use std::rc::Rc;
346 /// use std::cell::RefCell;
347 ///
348 /// let log = Rc::new(RefCell::new(Vec::new()));
349 /// let l = log.clone();
350 /// let consumer = RcConsumer::new(move |x: &i32| {
351 /// l.borrow_mut().push(*x);
352 /// });
353 /// let mut arc_consumer = consumer.to_arc();
354 /// arc_consumer.accept(&5);
355 /// assert_eq!(*log.borrow(), vec![5]);
356 /// // Original consumer still usable
357 /// consumer.accept(&3);
358 /// assert_eq!(*log.borrow(), vec![5, 3]);
359 /// ```
360 fn to_arc(&self) -> ArcConsumer<T>
361 where
362 Self: Sized + Clone + Send + 'static,
363 T: Send + 'static,
364 {
365 self.clone().into_arc()
366 }
367
368 /// Convert to closure
369 ///
370 /// **⚠️ Requires Clone**: The original consumer must implement Clone.
371 ///
372 /// Converts the consumer to a closure that can be used directly in standard
373 /// library functions requiring `FnMut`.
374 ///
375 /// # Ownership
376 ///
377 /// This method does **not consume** the consumer. It clones the consumer and
378 /// then converts the clone to a closure. The original consumer remains
379 /// available after calling this method.
380 ///
381 /// # Return Value
382 ///
383 /// Returns a closure implementing `FnMut(&T)` from the clone
384 ///
385 /// # Examples
386 ///
387 /// ```rust
388 /// use prism3_function::{Consumer, BoxConsumer};
389 /// use std::sync::{Arc, Mutex};
390 ///
391 /// let log = Arc::new(Mutex::new(Vec::new()));
392 /// let l = log.clone();
393 /// let consumer = BoxConsumer::new(move |x: &i32| {
394 /// l.lock().unwrap().push(*x);
395 /// });
396 /// let mut func = consumer.to_fn();
397 /// func(&5);
398 /// assert_eq!(*log.lock().unwrap(), vec![5]);
399 /// // Original consumer still usable
400 /// consumer.accept(&3);
401 /// assert_eq!(*log.lock().unwrap(), vec![5, 3]);
402 /// ```
403 fn to_fn(&self) -> impl FnMut(&T)
404 where
405 Self: Sized + Clone + 'static,
406 T: 'static,
407 {
408 self.clone().into_fn()
409 }
410}
411
412// ============================================================================
413// 2. BoxConsumer - Single Ownership Implementation
414// ============================================================================
415
416/// BoxConsumer struct
417///
418/// Consumer implementation based on `Box<dyn FnMut(&T)>` for single ownership
419/// scenarios. When sharing is not needed, this is the simplest and most
420/// efficient consumer type.
421///
422/// # Features
423///
424/// - **Single Ownership**: Not cloneable, transfers ownership when used
425/// - **Zero Overhead**: No reference counting or lock overhead
426/// - **Mutable State**: Can modify captured environment through `FnMut`
427/// - **Builder Pattern**: Method chaining naturally consumes `self`
428///
429/// # Use Cases
430///
431/// Choose `BoxConsumer` when:
432/// - Consumer is used only once or in a linear flow
433/// - Building pipelines where ownership flows naturally
434/// - No need to share consumers across contexts
435/// - Performance critical and cannot accept sharing overhead
436///
437/// # Performance
438///
439/// `BoxConsumer` has the best performance among the three consumer types:
440/// - No reference counting overhead
441/// - No lock acquisition or runtime borrowing checks
442/// - Direct function calls through vtable
443/// - Minimal memory footprint (single pointer)
444///
445/// # Examples
446///
447/// ```rust
448/// use prism3_function::{Consumer, BoxConsumer};
449/// use std::sync::{Arc, Mutex};
450///
451/// let log = Arc::new(Mutex::new(Vec::new()));
452/// let l = log.clone();
453/// let mut consumer = BoxConsumer::new(move |x: &i32| {
454/// l.lock().unwrap().push(*x);
455/// });
456/// consumer.accept(&5);
457/// assert_eq!(*log.lock().unwrap(), vec![5]);
458/// ```
459///
460/// # Author
461///
462/// Hu Haixing
463pub struct BoxConsumer<T> {
464 function: Box<dyn FnMut(&T)>,
465 name: Option<String>,
466}
467
468impl<T> BoxConsumer<T>
469where
470 T: 'static,
471{
472 /// Create a new BoxConsumer
473 ///
474 /// # Type Parameters
475 ///
476 /// * `F` - Closure type
477 ///
478 /// # Parameters
479 ///
480 /// * `f` - Closure to wrap
481 ///
482 /// # Return Value
483 ///
484 /// Returns a new `BoxConsumer<T>` instance
485 ///
486 /// # Examples
487 ///
488 /// ```rust
489 /// use prism3_function::{Consumer, BoxConsumer};
490 /// use std::sync::{Arc, Mutex};
491 ///
492 /// let log = Arc::new(Mutex::new(Vec::new()));
493 /// let l = log.clone();
494 /// let mut consumer = BoxConsumer::new(move |x: &i32| {
495 /// l.lock().unwrap().push(*x + 1);
496 /// });
497 /// consumer.accept(&5);
498 /// assert_eq!(*log.lock().unwrap(), vec![6]);
499 /// ```
500 pub fn new<F>(f: F) -> Self
501 where
502 F: FnMut(&T) + 'static,
503 {
504 BoxConsumer {
505 function: Box::new(f),
506 name: None,
507 }
508 }
509
510 /// Create a new named BoxConsumer
511 ///
512 /// # Type Parameters
513 ///
514 /// * `F` - Closure type
515 ///
516 /// # Parameters
517 ///
518 /// * `name` - Name of the consumer
519 /// * `f` - Closure to wrap
520 ///
521 /// # Return Value
522 ///
523 /// Returns a new `BoxConsumer<T>` instance
524 ///
525 /// # Examples
526 ///
527 /// ```rust
528 /// use prism3_function::{Consumer, BoxConsumer};
529 /// use std::sync::{Arc, Mutex};
530 ///
531 /// let log = Arc::new(Mutex::new(Vec::new()));
532 /// let l = log.clone();
533 /// let mut consumer = BoxConsumer::new_with_name("my_consumer", move |x: &i32| {
534 /// l.lock().unwrap().push(*x + 1);
535 /// });
536 /// assert_eq!(consumer.name(), Some("my_consumer"));
537 /// consumer.accept(&5);
538 /// assert_eq!(*log.lock().unwrap(), vec![6]);
539 /// ```
540 pub fn new_with_name<F>(name: impl Into<String>, f: F) -> Self
541 where
542 F: FnMut(&T) + 'static,
543 {
544 BoxConsumer {
545 function: Box::new(f),
546 name: Some(name.into()),
547 }
548 }
549
550 /// Create a no-op consumer
551 ///
552 /// Returns a consumer that performs no operation.
553 ///
554 /// # Return Value
555 ///
556 /// Returns a no-op consumer
557 ///
558 /// # Examples
559 ///
560 /// ```rust
561 /// use prism3_function::{Consumer, BoxConsumer};
562 ///
563 /// let mut noop = BoxConsumer::<i32>::noop();
564 /// noop.accept(&42);
565 /// // Value unchanged
566 /// ```
567 pub fn noop() -> Self {
568 BoxConsumer::new(|_| {})
569 }
570
571 /// Get the consumer's name
572 ///
573 /// # Return Value
574 ///
575 /// Returns the consumer's name, or `None` if not set
576 pub fn name(&self) -> Option<&str> {
577 self.name.as_deref()
578 }
579
580 /// Set the consumer's name
581 ///
582 /// # Parameters
583 ///
584 /// * `name` - Name to set
585 pub fn set_name(&mut self, name: impl Into<String>) {
586 self.name = Some(name.into());
587 }
588
589 /// Sequentially chain another consumer
590 ///
591 /// Returns a new consumer that executes the current operation first, then
592 /// the next operation. Consumes self.
593 ///
594 /// # Type Parameters
595 ///
596 /// * `C` - Type of the next consumer
597 ///
598 /// # Parameters
599 ///
600 /// * `next` - Consumer to execute after the current operation. **Note: This
601 /// parameter is passed by value and will transfer ownership.** If you need
602 /// to preserve the original consumer, clone it first (if it implements
603 /// `Clone`). Can be:
604 /// - A closure: `|x: &T|`
605 /// - A `BoxConsumer<T>`
606 /// - An `RcConsumer<T>`
607 /// - An `ArcConsumer<T>`
608 /// - Any type implementing `Consumer<T>`
609 ///
610 /// # Return Value
611 ///
612 /// Returns a new combined `BoxConsumer<T>`
613 ///
614 /// # Examples
615 ///
616 /// ## Direct value passing (ownership transfer)
617 ///
618 /// ```rust
619 /// use prism3_function::{Consumer, BoxConsumer};
620 /// use std::sync::{Arc, Mutex};
621 ///
622 /// let log = Arc::new(Mutex::new(Vec::new()));
623 /// let l1 = log.clone();
624 /// let l2 = log.clone();
625 /// let first = BoxConsumer::new(move |x: &i32| {
626 /// l1.lock().unwrap().push(*x * 2);
627 /// });
628 /// let second = BoxConsumer::new(move |x: &i32| {
629 /// l2.lock().unwrap().push(*x + 10);
630 /// });
631 ///
632 /// // second is moved here
633 /// let mut chained = first.and_then(second);
634 /// chained.accept(&5);
635 /// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
636 /// // second.accept(&3); // Would not compile - moved
637 /// ```
638 ///
639 /// ## Preserving original with clone
640 ///
641 /// ```rust
642 /// use prism3_function::{Consumer, BoxConsumer};
643 /// use std::sync::{Arc, Mutex};
644 ///
645 /// let log = Arc::new(Mutex::new(Vec::new()));
646 /// let l1 = log.clone();
647 /// let l2 = log.clone();
648 /// let first = BoxConsumer::new(move |x: &i32| {
649 /// l1.lock().unwrap().push(*x * 2);
650 /// });
651 /// let second = BoxConsumer::new(move |x: &i32| {
652 /// l2.lock().unwrap().push(*x + 10);
653 /// });
654 ///
655 /// // Clone to preserve original
656 /// let mut chained = first.and_then(second.clone());
657 /// chained.accept(&5);
658 /// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
659 ///
660 /// // Original still usable
661 /// second.accept(&3);
662 /// assert_eq!(*log.lock().unwrap(), vec![10, 15, 13]);
663 /// ```
664 pub fn and_then<C>(self, next: C) -> Self
665 where
666 C: Consumer<T> + 'static,
667 {
668 let mut first = self.function;
669 let mut second = next;
670 BoxConsumer::new(move |t| {
671 first(t);
672 second.accept(t);
673 })
674 }
675
676 /// Creates a conditional consumer
677 ///
678 /// Returns a consumer that only executes when a predicate is satisfied.
679 ///
680 /// # Parameters
681 ///
682 /// * `predicate` - The condition to check. **Note: This parameter is passed
683 /// by value and will transfer ownership.** If you need to preserve the
684 /// original predicate, clone it first (if it implements `Clone`). Can be:
685 /// - A closure: `|x: &T| -> bool`
686 /// - A function pointer: `fn(&T) -> bool`
687 /// - A `BoxPredicate<T>`
688 /// - An `RcPredicate<T>`
689 /// - An `ArcPredicate<T>`
690 /// - Any type implementing `Predicate<T>`
691 ///
692 /// # Return Value
693 ///
694 /// Returns `BoxConditionalConsumer<T>`
695 ///
696 /// # Examples
697 ///
698 /// ## Using a closure
699 ///
700 /// ```rust
701 /// use prism3_function::{Consumer, BoxConsumer};
702 /// use std::sync::{Arc, Mutex};
703 ///
704 /// let log = Arc::new(Mutex::new(Vec::new()));
705 /// let l = log.clone();
706 /// let consumer = BoxConsumer::new(move |x: &i32| {
707 /// l.lock().unwrap().push(*x);
708 /// });
709 /// let mut conditional = consumer.when(|x: &i32| *x > 0);
710 ///
711 /// conditional.accept(&5);
712 /// assert_eq!(*log.lock().unwrap(), vec![5]);
713 ///
714 /// conditional.accept(&-5);
715 /// assert_eq!(*log.lock().unwrap(), vec![5]); // Unchanged
716 /// ```
717 ///
718 /// ## Preserving predicate with clone
719 ///
720 /// ```rust
721 /// use prism3_function::{Consumer, BoxConsumer};
722 /// use prism3_function::predicate::{Predicate, RcPredicate};
723 /// use std::sync::{Arc, Mutex};
724 ///
725 /// let log = Arc::new(Mutex::new(Vec::new()));
726 /// let l = log.clone();
727 /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
728 /// let consumer = BoxConsumer::new(move |x: &i32| {
729 /// l.lock().unwrap().push(*x);
730 /// });
731 ///
732 /// // Clone to preserve original predicate
733 /// let mut conditional = consumer.when(is_positive.clone());
734 ///
735 /// conditional.accept(&5);
736 /// assert_eq!(*log.lock().unwrap(), vec![5]);
737 ///
738 /// // Original predicate still usable
739 /// assert!(is_positive.test(&3));
740 /// ```
741 pub fn when<P>(self, predicate: P) -> BoxConditionalConsumer<T>
742 where
743 P: Predicate<T> + 'static,
744 {
745 BoxConditionalConsumer {
746 consumer: self,
747 predicate: predicate.into_box(),
748 }
749 }
750}
751
752impl<T> Consumer<T> for BoxConsumer<T> {
753 fn accept(&mut self, value: &T) {
754 (self.function)(value)
755 }
756
757 fn into_box(self) -> BoxConsumer<T>
758 where
759 T: 'static,
760 {
761 self
762 }
763
764 fn into_rc(self) -> RcConsumer<T>
765 where
766 T: 'static,
767 {
768 let mut self_fn = self.function;
769 RcConsumer::new(move |t| self_fn(t))
770 }
771
772 // do NOT override Consumer::into_arc() because BoxConsumer is not Send + Sync
773 // and calling BoxConsumer::into_arc() will cause a compile error
774
775 fn into_fn(self) -> impl FnMut(&T)
776 where
777 T: 'static,
778 {
779 self.function
780 }
781
782 // do NOT override Consumer::to_xxx() because BoxConsumer is not Clone
783 // and calling BoxConsumer::to_xxx() will cause a compile error
784}
785
786impl<T> fmt::Debug for BoxConsumer<T> {
787 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
788 f.debug_struct("BoxConsumer")
789 .field("name", &self.name)
790 .field("function", &"<function>")
791 .finish()
792 }
793}
794
795impl<T> fmt::Display for BoxConsumer<T> {
796 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
797 match &self.name {
798 Some(name) => write!(f, "BoxConsumer({})", name),
799 None => write!(f, "BoxConsumer"),
800 }
801 }
802}
803
804// ============================================================================
805// 3. BoxConditionalConsumer - Box-based Conditional Consumer
806// ============================================================================
807
808/// BoxConditionalConsumer struct
809///
810/// A conditional consumer that only executes when a predicate is satisfied.
811/// Uses `BoxConsumer` and `BoxPredicate` for single ownership semantics.
812///
813/// This type is typically created by calling `BoxConsumer::when()` and is
814/// designed to work with the `or_else()` method to create if-then-else logic.
815///
816/// # Features
817///
818/// - **Single Ownership**: Not cloneable, consumes `self` on use
819/// - **Conditional Execution**: Only consumes when predicate returns `true`
820/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
821/// - **Implements Consumer**: Can be used anywhere a `Consumer` is expected
822///
823/// # Examples
824///
825/// ## Basic Conditional Execution
826///
827/// ```rust
828/// use prism3_function::{Consumer, BoxConsumer};
829/// use std::sync::{Arc, Mutex};
830///
831/// let log = Arc::new(Mutex::new(Vec::new()));
832/// let l = log.clone();
833/// let consumer = BoxConsumer::new(move |x: &i32| {
834/// l.lock().unwrap().push(*x);
835/// });
836/// let mut conditional = consumer.when(|x: &i32| *x > 0);
837///
838/// conditional.accept(&5);
839/// assert_eq!(*log.lock().unwrap(), vec![5]); // Executed
840///
841/// conditional.accept(&-5);
842/// assert_eq!(*log.lock().unwrap(), vec![5]); // Not executed
843/// ```
844///
845/// ## With or_else Branch
846///
847/// ```rust
848/// use prism3_function::{Consumer, BoxConsumer};
849/// use std::sync::{Arc, Mutex};
850///
851/// let log = Arc::new(Mutex::new(Vec::new()));
852/// let l1 = log.clone();
853/// let l2 = log.clone();
854/// let mut consumer = BoxConsumer::new(move |x: &i32| {
855/// l1.lock().unwrap().push(*x);
856/// })
857/// .when(|x: &i32| *x > 0)
858/// .or_else(move |x: &i32| {
859/// l2.lock().unwrap().push(-*x);
860/// });
861///
862/// consumer.accept(&5);
863/// assert_eq!(*log.lock().unwrap(), vec![5]); // when branch executed
864///
865/// consumer.accept(&-5);
866/// assert_eq!(*log.lock().unwrap(), vec![5, 5]); // or_else branch executed
867/// ```
868///
869/// # Author
870///
871/// Hu Haixing
872pub struct BoxConditionalConsumer<T> {
873 consumer: BoxConsumer<T>,
874 predicate: BoxPredicate<T>,
875}
876
877impl<T> Consumer<T> for BoxConditionalConsumer<T>
878where
879 T: 'static,
880{
881 fn accept(&mut self, value: &T) {
882 if self.predicate.test(value) {
883 self.consumer.accept(value);
884 }
885 }
886
887 fn into_box(self) -> BoxConsumer<T> {
888 let pred = self.predicate;
889 let mut consumer = self.consumer;
890 BoxConsumer::new(move |t| {
891 if pred.test(t) {
892 consumer.accept(t);
893 }
894 })
895 }
896
897 fn into_rc(self) -> RcConsumer<T> {
898 let pred = self.predicate.into_rc();
899 let consumer = self.consumer.into_rc();
900 let mut consumer_fn = consumer;
901 RcConsumer::new(move |t| {
902 if pred.test(t) {
903 consumer_fn.accept(t);
904 }
905 })
906 }
907
908 // do NOT override Consumer::into_arc() because BoxConditionalConsumer is not Send + Sync
909 // and calling BoxConditionalConsumer::into_arc() will cause a compile error
910
911 fn into_fn(self) -> impl FnMut(&T) {
912 let pred = self.predicate;
913 let mut consumer = self.consumer;
914 move |t: &T| {
915 if pred.test(t) {
916 consumer.accept(t);
917 }
918 }
919 }
920
921 // do NOT override Consumer::to_xxx() because BoxConditionalConsumer is not Clone
922 // and calling BoxConditionalConsumer::to_xxx() will cause a compile error
923}
924
925impl<T> BoxConditionalConsumer<T>
926where
927 T: 'static,
928{
929 /// Chains another consumer in sequence
930 ///
931 /// Combines the current conditional consumer with another consumer into a new
932 /// consumer. The current conditional consumer executes first, followed by the
933 /// next consumer.
934 ///
935 /// # Parameters
936 ///
937 /// * `next` - The next consumer to execute
938 ///
939 /// # Returns
940 ///
941 /// Returns a new `BoxConsumer<T>`
942 ///
943 /// # Examples
944 ///
945 /// ```rust
946 /// use prism3_function::{Consumer, BoxConsumer};
947 /// use std::sync::{Arc, Mutex};
948 ///
949 /// let log = Arc::new(Mutex::new(Vec::new()));
950 /// let l1 = log.clone();
951 /// let l2 = log.clone();
952 /// let cond1 = BoxConsumer::new(move |x: &i32| {
953 /// l1.lock().unwrap().push(*x * 2);
954 /// }).when(|x: &i32| *x > 0);
955 /// let cond2 = BoxConsumer::new(move |x: &i32| {
956 /// l2.lock().unwrap().push(*x + 100);
957 /// }).when(|x: &i32| *x > 10);
958 /// let mut chained = cond1.and_then(cond2);
959 ///
960 /// chained.accept(&6);
961 /// assert_eq!(*log.lock().unwrap(), vec![12, 106]);
962 /// // First *2 = 12, then +100 = 106
963 /// ```
964 pub fn and_then<C>(self, next: C) -> BoxConsumer<T>
965 where
966 C: Consumer<T> + 'static,
967 {
968 let mut first = self;
969 let mut second = next;
970 BoxConsumer::new(move |t| {
971 first.accept(t);
972 second.accept(t);
973 })
974 }
975
976 /// Adds an else branch
977 ///
978 /// Executes the original consumer when the condition is satisfied, otherwise
979 /// executes else_consumer.
980 ///
981 /// # Parameters
982 ///
983 /// * `else_consumer` - The consumer for the else branch, can be:
984 /// - Closure: `|x: &T|`
985 /// - `BoxConsumer<T>`, `RcConsumer<T>`, `ArcConsumer<T>`
986 /// - Any type implementing `Consumer<T>`
987 ///
988 /// # Returns
989 ///
990 /// Returns the composed `BoxConsumer<T>`
991 ///
992 /// # Examples
993 ///
994 /// ## Using a closure (recommended)
995 ///
996 /// ```rust
997 /// use prism3_function::{Consumer, BoxConsumer};
998 /// use std::sync::{Arc, Mutex};
999 ///
1000 /// let log = Arc::new(Mutex::new(Vec::new()));
1001 /// let l1 = log.clone();
1002 /// let l2 = log.clone();
1003 /// let mut consumer = BoxConsumer::new(move |x: &i32| {
1004 /// l1.lock().unwrap().push(*x);
1005 /// })
1006 /// .when(|x: &i32| *x > 0)
1007 /// .or_else(move |x: &i32| {
1008 /// l2.lock().unwrap().push(-*x);
1009 /// });
1010 ///
1011 /// consumer.accept(&5);
1012 /// assert_eq!(*log.lock().unwrap(), vec![5]);
1013 /// // Condition satisfied, execute first
1014 ///
1015 /// consumer.accept(&-5);
1016 /// assert_eq!(*log.lock().unwrap(), vec![5, 5]);
1017 /// // Condition not satisfied, execute else
1018 /// ```
1019 pub fn or_else<C>(self, else_consumer: C) -> BoxConsumer<T>
1020 where
1021 C: Consumer<T> + 'static,
1022 {
1023 let pred = self.predicate;
1024 let mut then_cons = self.consumer;
1025 let mut else_cons = else_consumer;
1026 BoxConsumer::new(move |t| {
1027 if pred.test(t) {
1028 then_cons.accept(t);
1029 } else {
1030 else_cons.accept(t);
1031 }
1032 })
1033 }
1034}
1035
1036// ============================================================================
1037// 4. ArcConsumer - Thread-Safe Shared Ownership Implementation
1038// ============================================================================
1039
1040/// ArcConsumer struct
1041///
1042/// Consumer implementation based on `Arc<Mutex<dyn FnMut(&T) + Send>>` for
1043/// thread-safe shared ownership scenarios. This consumer can be safely cloned
1044/// and shared across multiple threads.
1045///
1046/// # Features
1047///
1048/// - **Shared Ownership**: Cloneable through `Arc`, allowing multiple owners
1049/// - **Thread Safety**: Implements `Send + Sync`, safe for concurrent use
1050/// - **Interior Mutability**: Uses `Mutex` for safe mutable access
1051/// - **Non-Consuming API**: `and_then` borrows `&self`, original object remains
1052/// usable
1053/// - **Cross-Thread Sharing**: Can be sent to other threads and used
1054///
1055/// # Use Cases
1056///
1057/// Choose `ArcConsumer` when:
1058/// - Need to share consumers across multiple threads
1059/// - Concurrent task processing (e.g., thread pools)
1060/// - Using the same consumer in multiple places simultaneously
1061/// - Need thread safety (Send + Sync)
1062///
1063/// # Performance Considerations
1064///
1065/// `ArcConsumer` has some performance overhead compared to `BoxConsumer`:
1066/// - **Reference Counting**: Atomic operations on clone/drop
1067/// - **Mutex Locking**: Each `accept` call requires lock acquisition
1068/// - **Lock Contention**: High concurrency may cause contention
1069///
1070/// These overheads are necessary for safe concurrent access. If thread safety
1071/// is not needed, consider using `RcConsumer` for less single-threaded sharing
1072/// overhead.
1073///
1074/// # Examples
1075///
1076/// ```rust
1077/// use prism3_function::{Consumer, ArcConsumer};
1078/// use std::sync::{Arc, Mutex};
1079///
1080/// let log = Arc::new(Mutex::new(Vec::new()));
1081/// let l = log.clone();
1082/// let mut consumer = ArcConsumer::new(move |x: &i32| {
1083/// l.lock().unwrap().push(*x * 2);
1084/// });
1085/// let mut clone = consumer.clone();
1086///
1087/// consumer.accept(&5);
1088/// assert_eq!(*log.lock().unwrap(), vec![10]);
1089/// ```
1090///
1091/// # Author
1092///
1093/// Hu Haixing
1094pub struct ArcConsumer<T> {
1095 function: Arc<Mutex<SendConsumerFn<T>>>,
1096 name: Option<String>,
1097}
1098
1099impl<T> ArcConsumer<T>
1100where
1101 T: Send + 'static,
1102{
1103 /// Create a new ArcConsumer
1104 ///
1105 /// # Type Parameters
1106 ///
1107 /// * `F` - Closure type
1108 ///
1109 /// # Parameters
1110 ///
1111 /// * `f` - Closure to wrap
1112 ///
1113 /// # Return Value
1114 ///
1115 /// Returns a new `ArcConsumer<T>` instance
1116 ///
1117 /// # Examples
1118 ///
1119 /// ```rust
1120 /// use prism3_function::{Consumer, ArcConsumer};
1121 /// use std::sync::{Arc, Mutex};
1122 ///
1123 /// let log = Arc::new(Mutex::new(Vec::new()));
1124 /// let l = log.clone();
1125 /// let mut consumer = ArcConsumer::new(move |x: &i32| {
1126 /// l.lock().unwrap().push(*x + 1);
1127 /// });
1128 /// consumer.accept(&5);
1129 /// assert_eq!(*log.lock().unwrap(), vec![6]);
1130 /// ```
1131 pub fn new<F>(f: F) -> Self
1132 where
1133 F: FnMut(&T) + Send + 'static,
1134 {
1135 ArcConsumer {
1136 function: Arc::new(Mutex::new(f)),
1137 name: None,
1138 }
1139 }
1140
1141 /// Create a new named ArcConsumer
1142 ///
1143 /// # Type Parameters
1144 ///
1145 /// * `F` - Closure type
1146 ///
1147 /// # Parameters
1148 ///
1149 /// * `name` - Name of the consumer
1150 /// * `f` - Closure to wrap
1151 ///
1152 /// # Return Value
1153 ///
1154 /// Returns a new `ArcConsumer<T>` instance
1155 ///
1156 /// # Examples
1157 ///
1158 /// ```rust
1159 /// use prism3_function::{Consumer, ArcConsumer};
1160 /// use std::sync::{Arc, Mutex};
1161 ///
1162 /// let log = Arc::new(Mutex::new(Vec::new()));
1163 /// let l = log.clone();
1164 /// let mut consumer = ArcConsumer::new_with_name("my_consumer", move |x: &i32| {
1165 /// l.lock().unwrap().push(*x + 1);
1166 /// });
1167 /// assert_eq!(consumer.name(), Some("my_consumer"));
1168 /// consumer.accept(&5);
1169 /// assert_eq!(*log.lock().unwrap(), vec![6]);
1170 /// ```
1171 pub fn new_with_name<F>(name: impl Into<String>, f: F) -> Self
1172 where
1173 F: FnMut(&T) + Send + 'static,
1174 {
1175 ArcConsumer {
1176 function: Arc::new(Mutex::new(f)),
1177 name: Some(name.into()),
1178 }
1179 }
1180
1181 /// Create a no-op consumer
1182 ///
1183 /// Returns a consumer that performs no operation.
1184 ///
1185 /// # Return Value
1186 ///
1187 /// Returns a no-op consumer
1188 ///
1189 /// # Examples
1190 ///
1191 /// ```rust
1192 /// use prism3_function::{Consumer, ArcConsumer};
1193 ///
1194 /// let mut noop = ArcConsumer::<i32>::noop();
1195 /// noop.accept(&42);
1196 /// // Value unchanged
1197 /// ```
1198 pub fn noop() -> Self {
1199 ArcConsumer::new(|_| {})
1200 }
1201
1202 /// Get the consumer's name
1203 ///
1204 /// # Return Value
1205 ///
1206 /// Returns the consumer's name, or `None` if not set
1207 pub fn name(&self) -> Option<&str> {
1208 self.name.as_deref()
1209 }
1210
1211 /// Set the consumer's name
1212 ///
1213 /// # Parameters
1214 ///
1215 /// * `name` - Name to set
1216 pub fn set_name(&mut self, name: impl Into<String>) {
1217 self.name = Some(name.into());
1218 }
1219
1220 /// Sequentially chain another ArcConsumer
1221 ///
1222 /// Returns a new consumer that executes the current operation first, then the
1223 /// next operation. Borrows &self, does not consume the original consumer.
1224 ///
1225 /// # Parameters
1226 ///
1227 /// * `next` - Consumer to execute after the current operation
1228 ///
1229 /// # Return Value
1230 ///
1231 /// Returns a new combined `ArcConsumer<T>`
1232 ///
1233 /// # Examples
1234 ///
1235 /// ```rust
1236 /// use prism3_function::{Consumer, ArcConsumer};
1237 /// use std::sync::{Arc, Mutex};
1238 ///
1239 /// let log = Arc::new(Mutex::new(Vec::new()));
1240 /// let l1 = log.clone();
1241 /// let l2 = log.clone();
1242 /// let first = ArcConsumer::new(move |x: &i32| {
1243 /// l1.lock().unwrap().push(*x * 2);
1244 /// });
1245 /// let second = ArcConsumer::new(move |x: &i32| {
1246 /// l2.lock().unwrap().push(*x + 10);
1247 /// });
1248 ///
1249 /// let mut chained = first.and_then(&second);
1250 ///
1251 /// // first and second remain usable after chaining
1252 /// chained.accept(&5);
1253 /// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
1254 /// // (5 * 2), (5 + 10)
1255 /// ```
1256 pub fn and_then(&self, next: &ArcConsumer<T>) -> ArcConsumer<T> {
1257 let first = Arc::clone(&self.function);
1258 let second = Arc::clone(&next.function);
1259 ArcConsumer {
1260 function: Arc::new(Mutex::new(move |t: &T| {
1261 first.lock().unwrap()(t);
1262 second.lock().unwrap()(t);
1263 })),
1264 name: None,
1265 }
1266 }
1267
1268 /// Creates a conditional consumer (thread-safe version)
1269 ///
1270 /// Returns a consumer that only executes when a predicate is satisfied.
1271 ///
1272 /// # Parameters
1273 ///
1274 /// * `predicate` - The condition to check, must be `Send + Sync`, can be:
1275 /// - Closure: `|x: &T| -> bool` (requires `Send + Sync`)
1276 /// - Function pointer: `fn(&T) -> bool`
1277 /// - `ArcPredicate<T>`
1278 /// - Any type implementing `Predicate<T> + Send + Sync`
1279 ///
1280 /// # Returns
1281 ///
1282 /// Returns `ArcConditionalConsumer<T>`
1283 ///
1284 /// # Examples
1285 ///
1286 /// ```rust
1287 /// use prism3_function::{Consumer, ArcConsumer};
1288 /// use std::sync::{Arc, Mutex};
1289 ///
1290 /// let log = Arc::new(Mutex::new(Vec::new()));
1291 /// let l = log.clone();
1292 /// let consumer = ArcConsumer::new(move |x: &i32| {
1293 /// l.lock().unwrap().push(*x);
1294 /// });
1295 /// let conditional = consumer.when(|x: &i32| *x > 0);
1296 ///
1297 /// let conditional_clone = conditional.clone();
1298 ///
1299 /// let mut positive = 5;
1300 /// let mut m = conditional;
1301 /// m.accept(&positive);
1302 /// assert_eq!(*log.lock().unwrap(), vec![5]);
1303 /// ```
1304 pub fn when<P>(&self, predicate: P) -> ArcConditionalConsumer<T>
1305 where
1306 P: Predicate<T> + Send + Sync + 'static,
1307 T: Send + Sync,
1308 {
1309 ArcConditionalConsumer {
1310 consumer: self.clone(),
1311 predicate: predicate.into_arc(),
1312 }
1313 }
1314}
1315
1316impl<T> Consumer<T> for ArcConsumer<T> {
1317 fn accept(&mut self, value: &T) {
1318 (self.function.lock().unwrap())(value)
1319 }
1320
1321 fn into_box(self) -> BoxConsumer<T>
1322 where
1323 T: 'static,
1324 {
1325 let self_fn = self.function;
1326 BoxConsumer::new(move |t| self_fn.lock().unwrap()(t))
1327 }
1328
1329 fn into_rc(self) -> RcConsumer<T>
1330 where
1331 T: 'static,
1332 {
1333 let self_fn = self.function;
1334 RcConsumer::new(move |t| self_fn.lock().unwrap()(t))
1335 }
1336
1337 fn into_arc(self) -> ArcConsumer<T>
1338 where
1339 T: Send + 'static,
1340 {
1341 self
1342 }
1343
1344 fn into_fn(self) -> impl FnMut(&T)
1345 where
1346 T: 'static,
1347 {
1348 let self_fn = self.function;
1349 move |t: &T| {
1350 self_fn.lock().unwrap()(t);
1351 }
1352 }
1353
1354 fn to_box(&self) -> BoxConsumer<T>
1355 where
1356 T: 'static,
1357 {
1358 let self_fn = self.function.clone();
1359 BoxConsumer::new(move |t| self_fn.lock().unwrap()(t))
1360 }
1361
1362 fn to_rc(&self) -> RcConsumer<T>
1363 where
1364 T: 'static,
1365 {
1366 let self_fn = self.function.clone();
1367 RcConsumer::new(move |t| self_fn.lock().unwrap()(t))
1368 }
1369
1370 fn to_arc(&self) -> ArcConsumer<T>
1371 where
1372 T: Send + 'static,
1373 {
1374 self.clone()
1375 }
1376
1377 fn to_fn(&self) -> impl FnMut(&T) {
1378 let self_fn = self.function.clone();
1379 move |t| self_fn.lock().unwrap()(t)
1380 }
1381}
1382
1383impl<T> Clone for ArcConsumer<T> {
1384 /// Clone ArcConsumer
1385 ///
1386 /// Creates a new ArcConsumer that shares the underlying function with the
1387 /// original instance.
1388 fn clone(&self) -> Self {
1389 ArcConsumer {
1390 function: Arc::clone(&self.function),
1391 name: self.name.clone(),
1392 }
1393 }
1394}
1395
1396impl<T> fmt::Debug for ArcConsumer<T> {
1397 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1398 f.debug_struct("ArcConsumer")
1399 .field("name", &self.name)
1400 .field("function", &"<function>")
1401 .finish()
1402 }
1403}
1404
1405impl<T> fmt::Display for ArcConsumer<T> {
1406 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1407 match &self.name {
1408 Some(name) => write!(f, "ArcConsumer({})", name),
1409 None => write!(f, "ArcConsumer"),
1410 }
1411 }
1412}
1413
1414// ============================================================================
1415// 5. ArcConditionalConsumer - Arc-based Conditional Consumer
1416// ============================================================================
1417
1418/// ArcConditionalConsumer struct
1419///
1420/// A thread-safe conditional consumer that only executes when a predicate is
1421/// satisfied. Uses `ArcConsumer` and `ArcPredicate` for shared ownership across
1422/// threads.
1423///
1424/// This type is typically created by calling `ArcConsumer::when()` and is
1425/// designed to work with the `or_else()` method to create if-then-else logic.
1426///
1427/// # Features
1428///
1429/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
1430/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
1431/// - **Conditional Execution**: Only consumes when predicate returns `true`
1432/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
1433///
1434/// # Examples
1435///
1436/// ```rust
1437/// use prism3_function::{Consumer, ArcConsumer};
1438/// use std::sync::{Arc, Mutex};
1439///
1440/// let log = Arc::new(Mutex::new(Vec::new()));
1441/// let l = log.clone();
1442/// let conditional = ArcConsumer::new(move |x: &i32| {
1443/// l.lock().unwrap().push(*x);
1444/// })
1445/// .when(|x: &i32| *x > 0);
1446///
1447/// let conditional_clone = conditional.clone();
1448///
1449/// let mut value = 5;
1450/// let mut m = conditional;
1451/// m.accept(&value);
1452/// assert_eq!(*log.lock().unwrap(), vec![5]);
1453/// ```
1454///
1455/// # Author
1456///
1457/// Hu Haixing
1458pub struct ArcConditionalConsumer<T> {
1459 consumer: ArcConsumer<T>,
1460 predicate: ArcPredicate<T>,
1461}
1462
1463impl<T> Consumer<T> for ArcConditionalConsumer<T>
1464where
1465 T: Send + 'static,
1466{
1467 fn accept(&mut self, value: &T) {
1468 if self.predicate.test(value) {
1469 self.consumer.accept(value);
1470 }
1471 }
1472
1473 fn into_box(self) -> BoxConsumer<T>
1474 where
1475 T: 'static,
1476 {
1477 let pred = self.predicate;
1478 let mut consumer = self.consumer;
1479 BoxConsumer::new(move |t| {
1480 if pred.test(t) {
1481 consumer.accept(t);
1482 }
1483 })
1484 }
1485
1486 fn into_rc(self) -> RcConsumer<T>
1487 where
1488 T: 'static,
1489 {
1490 let pred = self.predicate.to_rc();
1491 let consumer = self.consumer.into_rc();
1492 let mut consumer_fn = consumer;
1493 RcConsumer::new(move |t| {
1494 if pred.test(t) {
1495 consumer_fn.accept(t);
1496 }
1497 })
1498 }
1499
1500 fn into_arc(self) -> ArcConsumer<T>
1501 where
1502 T: Send + 'static,
1503 {
1504 let pred = self.predicate;
1505 let mut consumer = self.consumer;
1506 ArcConsumer::new(move |t| {
1507 if pred.test(t) {
1508 consumer.accept(t);
1509 }
1510 })
1511 }
1512
1513 fn into_fn(self) -> impl FnMut(&T)
1514 where
1515 T: 'static,
1516 {
1517 let pred = self.predicate;
1518 let mut consumer = self.consumer;
1519 move |t: &T| {
1520 if pred.test(t) {
1521 consumer.accept(t);
1522 }
1523 }
1524 }
1525
1526 // inherit the default implementation of to_xxx() from Consumer
1527}
1528
1529impl<T> ArcConditionalConsumer<T>
1530where
1531 T: Send + 'static,
1532{
1533 /// Adds an else branch (thread-safe version)
1534 ///
1535 /// Executes the original consumer when the condition is satisfied, otherwise
1536 /// executes else_consumer.
1537 ///
1538 /// # Parameters
1539 ///
1540 /// * `else_consumer` - The consumer for the else branch, can be:
1541 /// - Closure: `|x: &T|` (must be `Send`)
1542 /// - `ArcConsumer<T>`, `BoxConsumer<T>`
1543 /// - Any type implementing `Consumer<T> + Send`
1544 ///
1545 /// # Returns
1546 ///
1547 /// Returns the composed `ArcConsumer<T>`
1548 ///
1549 /// # Examples
1550 ///
1551 /// ## Using a closure (recommended)
1552 ///
1553 /// ```rust
1554 /// use prism3_function::{Consumer, ArcConsumer};
1555 /// use std::sync::{Arc, Mutex};
1556 ///
1557 /// let log = Arc::new(Mutex::new(Vec::new()));
1558 /// let l1 = log.clone();
1559 /// let l2 = log.clone();
1560 /// let mut consumer = ArcConsumer::new(move |x: &i32| {
1561 /// l1.lock().unwrap().push(*x);
1562 /// })
1563 /// .when(|x: &i32| *x > 0)
1564 /// .or_else(move |x: &i32| {
1565 /// l2.lock().unwrap().push(-*x);
1566 /// });
1567 ///
1568 /// consumer.accept(&5);
1569 /// assert_eq!(*log.lock().unwrap(), vec![5]);
1570 ///
1571 /// consumer.accept(&-5);
1572 /// assert_eq!(*log.lock().unwrap(), vec![5, 5]);
1573 /// ```
1574 pub fn or_else<C>(&self, else_consumer: C) -> ArcConsumer<T>
1575 where
1576 C: Consumer<T> + Send + 'static,
1577 T: Send + Sync,
1578 {
1579 let pred = self.predicate.clone();
1580 let mut then_cons = self.consumer.clone();
1581 let mut else_cons = else_consumer;
1582
1583 ArcConsumer::new(move |t: &T| {
1584 if pred.test(t) {
1585 then_cons.accept(t);
1586 } else {
1587 else_cons.accept(t);
1588 }
1589 })
1590 }
1591}
1592
1593impl<T> Clone for ArcConditionalConsumer<T> {
1594 /// Clones the conditional consumer
1595 ///
1596 /// Creates a new instance that shares the underlying consumer and predicate
1597 /// with the original instance.
1598 fn clone(&self) -> Self {
1599 ArcConditionalConsumer {
1600 consumer: self.consumer.clone(),
1601 predicate: self.predicate.clone(),
1602 }
1603 }
1604}
1605
1606// ============================================================================
1607// 6. RcConsumer - Single-Threaded Shared Ownership Implementation
1608// ============================================================================
1609
1610/// RcConsumer struct
1611///
1612/// Consumer implementation based on `Rc<RefCell<dyn FnMut(&T)>>` for
1613/// single-threaded shared ownership scenarios. This consumer provides the
1614/// benefits of shared ownership without the overhead of thread safety.
1615///
1616/// # Features
1617///
1618/// - **Shared Ownership**: Cloneable through `Rc`, allowing multiple owners
1619/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
1620/// - **Interior Mutability**: Uses `RefCell` for runtime borrowing checks
1621/// - **No Lock Overhead**: More efficient than `ArcConsumer` for single-threaded
1622/// use
1623/// - **Non-Consuming API**: `and_then` borrows `&self`, original object remains
1624/// usable
1625///
1626/// # Use Cases
1627///
1628/// Choose `RcConsumer` when:
1629/// - Need to share consumers within a single thread
1630/// - Thread safety is not needed
1631/// - Performance is important (avoid lock overhead)
1632/// - UI event handling in single-threaded frameworks
1633/// - Building complex single-threaded state machines
1634///
1635/// # Performance Considerations
1636///
1637/// `RcConsumer` performs better than `ArcConsumer` in single-threaded scenarios:
1638/// - **Non-Atomic Counting**: clone/drop is cheaper than `Arc`
1639/// - **No Lock Overhead**: `RefCell` uses runtime checks, no locks
1640/// - **Better Cache Locality**: No atomic operations means better CPU cache
1641/// behavior
1642///
1643/// But still has slight overhead compared to `BoxConsumer`:
1644/// - **Reference Counting**: Non-atomic but still exists
1645/// - **Runtime Borrowing Checks**: `RefCell` checks at runtime
1646///
1647/// # Safety
1648///
1649/// `RcConsumer` is not thread-safe and does not implement `Send` or `Sync`.
1650/// Attempting to send it to another thread will result in a compilation error.
1651/// For thread-safe sharing, use `ArcConsumer` instead.
1652///
1653/// # Examples
1654///
1655/// ```rust
1656/// use prism3_function::{Consumer, RcConsumer};
1657/// use std::rc::Rc;
1658/// use std::cell::RefCell;
1659///
1660/// let log = Rc::new(RefCell::new(Vec::new()));
1661/// let l = log.clone();
1662/// let mut consumer = RcConsumer::new(move |x: &i32| {
1663/// l.borrow_mut().push(*x * 2);
1664/// });
1665/// let mut clone = consumer.clone();
1666///
1667/// consumer.accept(&5);
1668/// assert_eq!(*log.borrow(), vec![10]);
1669/// ```
1670///
1671/// # Author
1672///
1673/// Hu Haixing
1674pub struct RcConsumer<T> {
1675 function: Rc<RefCell<ConsumerFn<T>>>,
1676 name: Option<String>,
1677}
1678
1679impl<T> RcConsumer<T>
1680where
1681 T: 'static,
1682{
1683 /// Create a new RcConsumer
1684 ///
1685 /// # Type Parameters
1686 ///
1687 /// * `F` - Closure type
1688 ///
1689 /// # Parameters
1690 ///
1691 /// * `f` - Closure to wrap
1692 ///
1693 /// # Return Value
1694 ///
1695 /// Returns a new `RcConsumer<T>` instance
1696 ///
1697 /// # Examples
1698 ///
1699 /// ```rust
1700 /// use prism3_function::{Consumer, RcConsumer};
1701 /// use std::rc::Rc;
1702 /// use std::cell::RefCell;
1703 ///
1704 /// let log = Rc::new(RefCell::new(Vec::new()));
1705 /// let l = log.clone();
1706 /// let mut consumer = RcConsumer::new(move |x: &i32| {
1707 /// l.borrow_mut().push(*x + 1);
1708 /// });
1709 /// consumer.accept(&5);
1710 /// assert_eq!(*log.borrow(), vec![6]);
1711 /// ```
1712 pub fn new<F>(f: F) -> Self
1713 where
1714 F: FnMut(&T) + 'static,
1715 {
1716 RcConsumer {
1717 function: Rc::new(RefCell::new(f)),
1718 name: None,
1719 }
1720 }
1721
1722 /// Create a new named RcConsumer
1723 ///
1724 /// # Type Parameters
1725 ///
1726 /// * `F` - Closure type
1727 ///
1728 /// # Parameters
1729 ///
1730 /// * `name` - Name of the consumer
1731 /// * `f` - Closure to wrap
1732 ///
1733 /// # Return Value
1734 ///
1735 /// Returns a new `RcConsumer<T>` instance
1736 ///
1737 /// # Examples
1738 ///
1739 /// ```rust
1740 /// use prism3_function::{Consumer, RcConsumer};
1741 /// use std::rc::Rc;
1742 /// use std::cell::RefCell;
1743 ///
1744 /// let log = Rc::new(RefCell::new(Vec::new()));
1745 /// let l = log.clone();
1746 /// let mut consumer = RcConsumer::new_with_name("my_consumer", move |x: &i32| {
1747 /// l.borrow_mut().push(*x + 1);
1748 /// });
1749 /// assert_eq!(consumer.name(), Some("my_consumer"));
1750 /// consumer.accept(&5);
1751 /// assert_eq!(*log.borrow(), vec![6]);
1752 /// ```
1753 pub fn new_with_name<F>(name: impl Into<String>, f: F) -> Self
1754 where
1755 F: FnMut(&T) + 'static,
1756 {
1757 RcConsumer {
1758 function: Rc::new(RefCell::new(f)),
1759 name: Some(name.into()),
1760 }
1761 }
1762
1763 /// Create a no-op consumer
1764 ///
1765 /// Returns a consumer that performs no operation.
1766 ///
1767 /// # Return Value
1768 ///
1769 /// Returns a no-op consumer
1770 ///
1771 /// # Examples
1772 ///
1773 /// ```rust
1774 /// use prism3_function::{Consumer, RcConsumer};
1775 ///
1776 /// let mut noop = RcConsumer::<i32>::noop();
1777 /// noop.accept(&42);
1778 /// // Value unchanged
1779 /// ```
1780 pub fn noop() -> Self {
1781 RcConsumer::new(|_| {})
1782 }
1783
1784 /// Get the consumer's name
1785 ///
1786 /// # Return Value
1787 ///
1788 /// Returns the consumer's name, or `None` if not set
1789 pub fn name(&self) -> Option<&str> {
1790 self.name.as_deref()
1791 }
1792
1793 /// Set the consumer's name
1794 ///
1795 /// # Parameters
1796 ///
1797 /// * `name` - Name to set
1798 pub fn set_name(&mut self, name: impl Into<String>) {
1799 self.name = Some(name.into());
1800 }
1801
1802 /// Sequentially chain another RcConsumer
1803 ///
1804 /// Returns a new consumer that executes the current operation first, then the
1805 /// next operation. Borrows &self, does not consume the original consumer.
1806 ///
1807 /// # Parameters
1808 ///
1809 /// * `next` - Consumer to execute after the current operation
1810 ///
1811 /// # Return Value
1812 ///
1813 /// Returns a new combined `RcConsumer<T>`
1814 ///
1815 /// # Examples
1816 ///
1817 /// ```rust
1818 /// use prism3_function::{Consumer, RcConsumer};
1819 /// use std::rc::Rc;
1820 /// use std::cell::RefCell;
1821 ///
1822 /// let log = Rc::new(RefCell::new(Vec::new()));
1823 /// let l1 = log.clone();
1824 /// let l2 = log.clone();
1825 /// let first = RcConsumer::new(move |x: &i32| {
1826 /// l1.borrow_mut().push(*x * 2);
1827 /// });
1828 /// let second = RcConsumer::new(move |x: &i32| {
1829 /// l2.borrow_mut().push(*x + 10);
1830 /// });
1831 ///
1832 /// let mut chained = first.and_then(&second);
1833 ///
1834 /// // first and second remain usable after chaining
1835 /// chained.accept(&5);
1836 /// assert_eq!(*log.borrow(), vec![10, 15]);
1837 /// // (5 * 2), (5 + 10)
1838 /// ```
1839 pub fn and_then(&self, next: &RcConsumer<T>) -> RcConsumer<T> {
1840 let first = Rc::clone(&self.function);
1841 let second = Rc::clone(&next.function);
1842 RcConsumer {
1843 function: Rc::new(RefCell::new(move |t: &T| {
1844 first.borrow_mut()(t);
1845 second.borrow_mut()(t);
1846 })),
1847 name: None,
1848 }
1849 }
1850
1851 /// Creates a conditional consumer (single-threaded shared version)
1852 ///
1853 /// Returns a consumer that only executes when a predicate is satisfied.
1854 ///
1855 /// # Parameters
1856 ///
1857 /// * `predicate` - The condition to check, can be:
1858 /// - Closure: `|x: &T| -> bool`
1859 /// - Function pointer: `fn(&T) -> bool`
1860 /// - `RcPredicate<T>`, `BoxPredicate<T>`
1861 /// - Any type implementing `Predicate<T>`
1862 ///
1863 /// # Returns
1864 ///
1865 /// Returns `RcConditionalConsumer<T>`
1866 ///
1867 /// # Examples
1868 ///
1869 /// ```rust
1870 /// use prism3_function::{Consumer, RcConsumer};
1871 /// use std::rc::Rc;
1872 /// use std::cell::RefCell;
1873 ///
1874 /// let log = Rc::new(RefCell::new(Vec::new()));
1875 /// let l = log.clone();
1876 /// let consumer = RcConsumer::new(move |x: &i32| {
1877 /// l.borrow_mut().push(*x);
1878 /// });
1879 /// let conditional = consumer.when(|x: &i32| *x > 0);
1880 ///
1881 /// let conditional_clone = conditional.clone();
1882 ///
1883 /// let mut positive = 5;
1884 /// let mut m = conditional;
1885 /// m.accept(&positive);
1886 /// assert_eq!(*log.borrow(), vec![5]);
1887 /// ```
1888 pub fn when<P>(&self, predicate: P) -> RcConditionalConsumer<T>
1889 where
1890 P: Predicate<T> + 'static,
1891 {
1892 RcConditionalConsumer {
1893 consumer: self.clone(),
1894 predicate: predicate.into_rc(),
1895 }
1896 }
1897}
1898
1899impl<T> Consumer<T> for RcConsumer<T> {
1900 fn accept(&mut self, value: &T) {
1901 (self.function.borrow_mut())(value)
1902 }
1903
1904 fn into_box(self) -> BoxConsumer<T>
1905 where
1906 T: 'static,
1907 {
1908 let self_fn = self.function;
1909 BoxConsumer::new(move |t| self_fn.borrow_mut()(t))
1910 }
1911
1912 fn into_rc(self) -> RcConsumer<T>
1913 where
1914 T: 'static,
1915 {
1916 self
1917 }
1918
1919 // do NOT override Consumer::into_arc() because RcConsumer is not Send + Sync
1920 // and calling RcConsumer::into_arc() will cause a compile error
1921
1922 fn into_fn(self) -> impl FnMut(&T)
1923 where
1924 T: 'static,
1925 {
1926 let self_fn = self.function;
1927 move |t| self_fn.borrow_mut()(t)
1928 }
1929
1930 fn to_box(&self) -> BoxConsumer<T>
1931 where
1932 T: 'static,
1933 {
1934 let self_fn = self.function.clone();
1935 BoxConsumer::new(move |t| self_fn.borrow_mut()(t))
1936 }
1937
1938 fn to_rc(&self) -> RcConsumer<T>
1939 where
1940 T: 'static,
1941 {
1942 self.clone()
1943 }
1944
1945 // do NOT override Consumer::to_arc() because RcConsumer is not Send + Sync
1946 // and calling RcConsumer::to_arc() will cause a compile error
1947
1948 fn to_fn(&self) -> impl FnMut(&T) {
1949 let self_fn = self.function.clone();
1950 move |t| self_fn.borrow_mut()(t)
1951 }
1952}
1953
1954impl<T> Clone for RcConsumer<T> {
1955 /// Clone RcConsumer
1956 ///
1957 /// Creates a new RcConsumer that shares the underlying function with the
1958 /// original instance.
1959 fn clone(&self) -> Self {
1960 RcConsumer {
1961 function: self.function.clone(),
1962 name: self.name.clone(),
1963 }
1964 }
1965}
1966
1967impl<T> fmt::Debug for RcConsumer<T> {
1968 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1969 f.debug_struct("RcConsumer")
1970 .field("name", &self.name)
1971 .field("function", &"<function>")
1972 .finish()
1973 }
1974}
1975
1976impl<T> fmt::Display for RcConsumer<T> {
1977 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1978 match &self.name {
1979 Some(name) => write!(f, "RcConsumer({})", name),
1980 None => write!(f, "RcConsumer"),
1981 }
1982 }
1983}
1984
1985// ============================================================================
1986// 7. RcConditionalConsumer - Rc-based Conditional Consumer
1987// ============================================================================
1988
1989/// RcConditionalConsumer struct
1990///
1991/// A single-threaded conditional consumer that only executes when a predicate is
1992/// satisfied. Uses `RcConsumer` and `RcPredicate` for shared ownership within a
1993/// single thread.
1994///
1995/// This type is typically created by calling `RcConsumer::when()` and is
1996/// designed to work with the `or_else()` method to create if-then-else logic.
1997///
1998/// # Features
1999///
2000/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
2001/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
2002/// - **Conditional Execution**: Only consumes when predicate returns `true`
2003/// - **No Lock Overhead**: More efficient than `ArcConditionalConsumer`
2004///
2005/// # Examples
2006///
2007/// ```rust
2008/// use prism3_function::{Consumer, RcConsumer};
2009/// use std::rc::Rc;
2010/// use std::cell::RefCell;
2011///
2012/// let log = Rc::new(RefCell::new(Vec::new()));
2013/// let l = log.clone();
2014/// let conditional = RcConsumer::new(move |x: &i32| {
2015/// l.borrow_mut().push(*x);
2016/// })
2017/// .when(|x: &i32| *x > 0);
2018///
2019/// let conditional_clone = conditional.clone();
2020///
2021/// let mut value = 5;
2022/// let mut m = conditional;
2023/// m.accept(&value);
2024/// assert_eq!(*log.borrow(), vec![5]);
2025/// ```
2026///
2027/// # Author
2028///
2029/// Hu Haixing
2030pub struct RcConditionalConsumer<T> {
2031 consumer: RcConsumer<T>,
2032 predicate: RcPredicate<T>,
2033}
2034
2035impl<T> Consumer<T> for RcConditionalConsumer<T>
2036where
2037 T: 'static,
2038{
2039 fn accept(&mut self, value: &T) {
2040 if self.predicate.test(value) {
2041 self.consumer.accept(value);
2042 }
2043 }
2044
2045 fn into_box(self) -> BoxConsumer<T> {
2046 let pred = self.predicate;
2047 let mut consumer = self.consumer;
2048 BoxConsumer::new(move |t| {
2049 if pred.test(t) {
2050 consumer.accept(t);
2051 }
2052 })
2053 }
2054
2055 fn into_rc(self) -> RcConsumer<T> {
2056 let pred = self.predicate;
2057 let mut consumer = self.consumer;
2058 RcConsumer::new(move |t| {
2059 if pred.test(t) {
2060 consumer.accept(t);
2061 }
2062 })
2063 }
2064
2065 // do NOT override Consumer::into_arc() because RcConditionalConsumer is not Send + Sync
2066 // and calling RcConditionalConsumer::into_arc() will cause a compile error
2067
2068 fn into_fn(self) -> impl FnMut(&T) {
2069 let pred = self.predicate;
2070 let mut consumer = self.consumer;
2071 move |t: &T| {
2072 if pred.test(t) {
2073 consumer.accept(t);
2074 }
2075 }
2076 }
2077
2078 // inherit the default implementation of to_xxx() from Consumer
2079}
2080
2081impl<T> RcConditionalConsumer<T>
2082where
2083 T: 'static,
2084{
2085 /// Adds an else branch (single-threaded shared version)
2086 ///
2087 /// Executes the original consumer when the condition is satisfied, otherwise
2088 /// executes else_consumer.
2089 ///
2090 /// # Parameters
2091 ///
2092 /// * `else_consumer` - The consumer for the else branch, can be:
2093 /// - Closure: `|x: &T|`
2094 /// - `RcConsumer<T>`, `BoxConsumer<T>`
2095 /// - Any type implementing `Consumer<T>`
2096 ///
2097 /// # Returns
2098 ///
2099 /// Returns the composed `RcConsumer<T>`
2100 ///
2101 /// # Examples
2102 ///
2103 /// ## Using a closure (recommended)
2104 ///
2105 /// ```rust
2106 /// use prism3_function::{Consumer, RcConsumer};
2107 /// use std::rc::Rc;
2108 /// use std::cell::RefCell;
2109 ///
2110 /// let log = Rc::new(RefCell::new(Vec::new()));
2111 /// let l1 = log.clone();
2112 /// let l2 = log.clone();
2113 /// let mut consumer = RcConsumer::new(move |x: &i32| {
2114 /// l1.borrow_mut().push(*x);
2115 /// })
2116 /// .when(|x: &i32| *x > 0)
2117 /// .or_else(move |x: &i32| {
2118 /// l2.borrow_mut().push(-*x);
2119 /// });
2120 ///
2121 /// consumer.accept(&5);
2122 /// assert_eq!(*log.borrow(), vec![5]);
2123 ///
2124 /// consumer.accept(&-5);
2125 /// assert_eq!(*log.borrow(), vec![5, 5]);
2126 /// ```
2127 pub fn or_else<C>(&self, else_consumer: C) -> RcConsumer<T>
2128 where
2129 C: Consumer<T> + 'static,
2130 {
2131 let pred = self.predicate.clone();
2132 let mut then_cons = self.consumer.clone();
2133 let mut else_cons = else_consumer;
2134
2135 RcConsumer::new(move |t: &T| {
2136 if pred.test(t) {
2137 then_cons.accept(t);
2138 } else {
2139 else_cons.accept(t);
2140 }
2141 })
2142 }
2143}
2144
2145impl<T> Clone for RcConditionalConsumer<T> {
2146 /// Clones the conditional consumer
2147 ///
2148 /// Creates a new instance that shares the underlying consumer and predicate
2149 /// with the original instance.
2150 fn clone(&self) -> Self {
2151 RcConditionalConsumer {
2152 consumer: self.consumer.clone(),
2153 predicate: self.predicate.clone(),
2154 }
2155 }
2156}
2157
2158// ============================================================================
2159// 8. Implement Consumer trait for closures
2160// ============================================================================
2161
2162/// Implement Consumer for all FnMut(&T)
2163impl<T, F> Consumer<T> for F
2164where
2165 F: FnMut(&T),
2166{
2167 fn accept(&mut self, value: &T) {
2168 self(value)
2169 }
2170
2171 fn into_box(self) -> BoxConsumer<T>
2172 where
2173 Self: Sized + 'static,
2174 T: 'static,
2175 {
2176 BoxConsumer::new(self)
2177 }
2178
2179 fn into_rc(self) -> RcConsumer<T>
2180 where
2181 Self: Sized + 'static,
2182 T: 'static,
2183 {
2184 RcConsumer::new(self)
2185 }
2186
2187 fn into_arc(self) -> ArcConsumer<T>
2188 where
2189 Self: Sized + Send + 'static,
2190 T: Send + 'static,
2191 {
2192 ArcConsumer::new(self)
2193 }
2194
2195 fn into_fn(self) -> impl FnMut(&T)
2196 where
2197 Self: Sized + 'static,
2198 T: 'static,
2199 {
2200 self
2201 }
2202
2203 fn to_box(&self) -> BoxConsumer<T>
2204 where
2205 Self: Sized + Clone + 'static,
2206 T: 'static,
2207 {
2208 let cloned = self.clone();
2209 BoxConsumer::new(cloned)
2210 }
2211
2212 fn to_rc(&self) -> RcConsumer<T>
2213 where
2214 Self: Sized + Clone + 'static,
2215 T: 'static,
2216 {
2217 let cloned = self.clone();
2218 RcConsumer::new(cloned)
2219 }
2220
2221 fn to_arc(&self) -> ArcConsumer<T>
2222 where
2223 Self: Sized + Clone + Send + 'static,
2224 T: Send + 'static,
2225 {
2226 let cloned = self.clone();
2227 ArcConsumer::new(cloned)
2228 }
2229
2230 fn to_fn(&self) -> impl FnMut(&T)
2231 where
2232 Self: Sized + Clone + 'static,
2233 T: 'static,
2234 {
2235 self.clone()
2236 }
2237}
2238
2239// ============================================================================
2240// 9. Extension methods for closures
2241// ============================================================================
2242
2243/// Extension trait providing consumer composition methods for closures
2244///
2245/// Provides `and_then` and other composition methods for all closures
2246/// implementing `FnMut(&T)`, allowing direct method chaining on closures
2247/// without explicit wrapper types.
2248///
2249/// # Design Philosophy
2250///
2251/// This trait allows closures to be naturally composed using method syntax,
2252/// similar to iterator combinators. Composition methods consume the closure and
2253/// return `BoxConsumer<T>`, which can continue chaining.
2254///
2255/// # Features
2256///
2257/// - **Natural Syntax**: Direct method chaining on closures
2258/// - **Returns BoxConsumer**: Composition results in `BoxConsumer<T>`, can
2259/// continue chaining
2260/// - **Zero Cost**: No overhead when composing closures
2261/// - **Automatic Implementation**: All `FnMut(&T)` closures automatically get
2262/// these methods
2263///
2264/// # Examples
2265///
2266/// ```rust
2267/// use prism3_function::{Consumer, FnConsumerOps};
2268/// use std::sync::{Arc, Mutex};
2269///
2270/// let log = Arc::new(Mutex::new(Vec::new()));
2271/// let l1 = log.clone();
2272/// let l2 = log.clone();
2273/// let mut chained = (move |x: &i32| {
2274/// l1.lock().unwrap().push(*x * 2);
2275/// }).and_then(move |x: &i32| {
2276/// l2.lock().unwrap().push(*x + 10);
2277/// });
2278/// chained.accept(&5);
2279/// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
2280/// // (5 * 2), (5 + 10)
2281/// ```
2282///
2283/// # Author
2284///
2285/// Hu Haixing
2286pub trait FnConsumerOps<T>: FnMut(&T) + Sized {
2287 /// Sequentially chain another consumer
2288 ///
2289 /// Returns a new consumer that executes the current operation first, then the
2290 /// next operation. Consumes the current closure and returns `BoxConsumer<T>`.
2291 ///
2292 /// # Type Parameters
2293 ///
2294 /// * `C` - Type of the next consumer
2295 ///
2296 /// # Parameters
2297 ///
2298 /// * `next` - Consumer to execute after the current operation. **Note: This
2299 /// parameter is passed by value and will transfer ownership.** If you need
2300 /// to preserve the original consumer, clone it first (if it implements
2301 /// `Clone`). Can be:
2302 /// - A closure: `|x: &T|`
2303 /// - A `BoxConsumer<T>`
2304 /// - An `RcConsumer<T>`
2305 /// - An `ArcConsumer<T>`
2306 /// - Any type implementing `Consumer<T>`
2307 ///
2308 /// # Return Value
2309 ///
2310 /// Returns a combined `BoxConsumer<T>`
2311 ///
2312 /// # Examples
2313 ///
2314 /// ## Direct value passing (ownership transfer)
2315 ///
2316 /// ```rust
2317 /// use prism3_function::{Consumer, FnConsumerOps, BoxConsumer};
2318 /// use std::sync::{Arc, Mutex};
2319 ///
2320 /// let log = Arc::new(Mutex::new(Vec::new()));
2321 /// let l1 = log.clone();
2322 /// let l2 = log.clone();
2323 /// let second = BoxConsumer::new(move |x: &i32| {
2324 /// l2.lock().unwrap().push(*x + 10);
2325 /// });
2326 ///
2327 /// // second is moved here
2328 /// let mut chained = (move |x: &i32| {
2329 /// l1.lock().unwrap().push(*x * 2);
2330 /// }).and_then(second);
2331 ///
2332 /// chained.accept(&5);
2333 /// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
2334 /// // second.accept(&3); // Would not compile - moved
2335 /// ```
2336 ///
2337 /// ## Preserving original with clone
2338 ///
2339 /// ```rust
2340 /// use prism3_function::{Consumer, FnConsumerOps, BoxConsumer};
2341 /// use std::sync::{Arc, Mutex};
2342 ///
2343 /// let log = Arc::new(Mutex::new(Vec::new()));
2344 /// let l1 = log.clone();
2345 /// let l2 = log.clone();
2346 /// let second = BoxConsumer::new(move |x: &i32| {
2347 /// l2.lock().unwrap().push(*x + 10);
2348 /// });
2349 ///
2350 /// // Clone to preserve original
2351 /// let mut chained = (move |x: &i32| {
2352 /// l1.lock().unwrap().push(*x * 2);
2353 /// }).and_then(second.clone());
2354 ///
2355 /// chained.accept(&5);
2356 /// assert_eq!(*log.lock().unwrap(), vec![10, 15]);
2357 ///
2358 /// // Original still usable
2359 /// second.accept(&3);
2360 /// assert_eq!(*log.lock().unwrap(), vec![10, 15, 13]);
2361 /// ```
2362 fn and_then<C>(self, next: C) -> BoxConsumer<T>
2363 where
2364 Self: 'static,
2365 C: Consumer<T> + 'static,
2366 T: 'static,
2367 {
2368 let mut first = self;
2369 let mut second = next;
2370 BoxConsumer::new(move |t| {
2371 first(t);
2372 second.accept(t);
2373 })
2374 }
2375}
2376
2377/// Implement FnConsumerOps for all closure types
2378impl<T, F> FnConsumerOps<T> for F where F: FnMut(&T) {}