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