prism3_function/
readonly_consumer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # ReadonlyConsumer Types
10//!
11//! Provides implementations of readonly consumer interfaces for executing operations that neither modify their own state nor modify input values.
12//!
13//! This module provides a unified `ReadonlyConsumer` trait and three concrete implementations based on different ownership models:
14//!
15//! - **`BoxReadonlyConsumer<T>`**: Box-based single ownership implementation
16//! - **`ArcReadonlyConsumer<T>`**: Arc-based thread-safe shared ownership implementation
17//! - **`RcReadonlyConsumer<T>`**: Rc-based single-threaded shared ownership implementation
18//!
19//! # Design Philosophy
20//!
21//! ReadonlyConsumer uses `Fn(&T)` semantics, neither modifying its own state nor modifying input values.
22//! Suitable for pure observation, logging, notification and other scenarios. Compared to Consumer, ReadonlyConsumer
23//! does not require interior mutability (Mutex/RefCell), making it more efficient and easier to share.
24//!
25//! # Author
26//!
27//! Hu Haixing
28
29use std::fmt;
30use std::rc::Rc;
31use std::sync::Arc;
32
33// ============================================================================
34// 1. ReadonlyConsumer Trait - Unified ReadonlyConsumer Interface
35// ============================================================================
36
37/// ReadonlyConsumer trait - Unified readonly consumer interface
38///
39/// Defines the core behavior of all readonly consumer types. Unlike `Consumer`, `ReadonlyConsumer`
40/// neither modifies its own state nor modifies input values, making it a completely immutable operation.
41///
42/// # Auto-implementation
43///
44/// - All closures implementing `Fn(&T)`
45/// - `BoxReadonlyConsumer<T>`, `ArcReadonlyConsumer<T>`, `RcReadonlyConsumer<T>`
46///
47/// # Features
48///
49/// - **Unified Interface**: All readonly consumer types share the same `accept` method signature
50/// - **Auto-implementation**: Closures automatically implement this trait with zero overhead
51/// - **Type Conversion**: Easy conversion between different ownership models
52/// - **Generic Programming**: Write functions that work with any readonly consumer type
53/// - **No Interior Mutability**: No need for Mutex or RefCell, more efficient
54///
55/// # Examples
56///
57/// ```rust
58/// use prism3_function::{ReadonlyConsumer, BoxReadonlyConsumer};
59///
60/// fn apply_consumer<C: ReadonlyConsumer<i32>>(consumer: &C, value: &i32) {
61///     consumer.accept(value);
62/// }
63///
64/// let box_con = BoxReadonlyConsumer::new(|x: &i32| {
65///     println!("Value: {}", x);
66/// });
67/// apply_consumer(&box_con, &5);
68/// ```
69///
70/// # Author
71///
72/// Hu Haixing
73pub trait ReadonlyConsumer<T> {
74    /// Execute readonly consumption operation
75    ///
76    /// Performs an operation on the given reference. The operation typically reads input values or produces side effects,
77    /// but neither modifies the input value nor the consumer's own state.
78    ///
79    /// # Parameters
80    ///
81    /// * `value` - Reference to the value to consume
82    ///
83    /// # Examples
84    ///
85    /// ```rust
86    /// use prism3_function::{ReadonlyConsumer, BoxReadonlyConsumer};
87    ///
88    /// let consumer = BoxReadonlyConsumer::new(|x: &i32| println!("{}", x));
89    /// consumer.accept(&5);
90    /// ```
91    fn accept(&self, value: &T);
92
93    /// Convert to BoxReadonlyConsumer
94    ///
95    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after calling this method.
96    ///
97    /// # Returns
98    ///
99    /// Returns the wrapped `BoxReadonlyConsumer<T>`
100    fn into_box(self) -> BoxReadonlyConsumer<T>
101    where
102        Self: Sized + 'static,
103        T: 'static;
104
105    /// Convert to RcReadonlyConsumer
106    ///
107    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after calling this method.
108    ///
109    /// # Returns
110    ///
111    /// Returns the wrapped `RcReadonlyConsumer<T>`
112    fn into_rc(self) -> RcReadonlyConsumer<T>
113    where
114        Self: Sized + 'static,
115        T: 'static;
116
117    /// Convert to ArcReadonlyConsumer
118    ///
119    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after calling this method.
120    ///
121    /// # Returns
122    ///
123    /// Returns the wrapped `ArcReadonlyConsumer<T>`
124    fn into_arc(self) -> ArcReadonlyConsumer<T>
125    where
126        Self: Sized + Send + Sync + 'static,
127        T: Send + Sync + 'static;
128
129    /// Convert to closure
130    ///
131    /// **⚠️ Consumes `self`**: The original consumer will be unavailable after calling this method.
132    ///
133    /// Converts a readonly consumer to a closure that can be used directly in places where the standard library requires `Fn`.
134    ///
135    /// # Returns
136    ///
137    /// Returns a closure implementing `Fn(&T)`
138    ///
139    /// # Examples
140    ///
141    /// ```rust
142    /// use prism3_function::{ReadonlyConsumer, BoxReadonlyConsumer};
143    ///
144    /// let consumer = BoxReadonlyConsumer::new(|x: &i32| {
145    ///     println!("Value: {}", x);
146    /// });
147    /// let func = consumer.into_fn();
148    /// func(&5);
149    /// ```
150    fn into_fn(self) -> impl Fn(&T)
151    where
152        Self: Sized + 'static,
153        T: 'static;
154}
155
156// ============================================================================
157// 2. BoxReadonlyConsumer - Single Ownership Implementation
158// ============================================================================
159
160/// BoxReadonlyConsumer struct
161///
162/// Readonly consumer implementation based on `Box<dyn Fn(&T)>` for single ownership scenarios.
163///
164/// # Features
165///
166/// - **Single Ownership**: Not cloneable, transfers ownership when used
167/// - **Zero Overhead**: No reference counting or lock overhead
168/// - **Completely Immutable**: Neither modifies itself nor input
169/// - **No Interior Mutability**: No need for Mutex or RefCell
170///
171/// # Use Cases
172///
173/// Choose `BoxReadonlyConsumer` when:
174/// - Readonly consumer is used once or in a linear flow
175/// - No need to share consumer across contexts
176/// - Pure observation operations, such as logging
177///
178/// # Examples
179///
180/// ```rust
181/// use prism3_function::{ReadonlyConsumer, BoxReadonlyConsumer};
182///
183/// let consumer = BoxReadonlyConsumer::new(|x: &i32| {
184///     println!("Observed value: {}", x);
185/// });
186/// consumer.accept(&5);
187/// ```
188///
189/// # Author
190///
191/// Hu Haixing
192pub struct BoxReadonlyConsumer<T> {
193    function: Box<dyn Fn(&T)>,
194    name: Option<String>,
195}
196
197impl<T> BoxReadonlyConsumer<T>
198where
199    T: 'static,
200{
201    /// Create a new BoxReadonlyConsumer
202    ///
203    /// # Type Parameters
204    ///
205    /// * `F` - Closure type
206    ///
207    /// # Parameters
208    ///
209    /// * `f` - Closure to wrap
210    ///
211    /// # Returns
212    ///
213    /// Returns a new `BoxReadonlyConsumer<T>` instance
214    ///
215    /// # Examples
216    ///
217    /// ```rust
218    /// use prism3_function::{ReadonlyConsumer, BoxReadonlyConsumer};
219    ///
220    /// let consumer = BoxReadonlyConsumer::new(|x: &i32| {
221    ///     println!("Value: {}", x);
222    /// });
223    /// consumer.accept(&5);
224    /// ```
225    pub fn new<F>(f: F) -> Self
226    where
227        F: Fn(&T) + 'static,
228    {
229        BoxReadonlyConsumer {
230            function: Box::new(f),
231            name: None,
232        }
233    }
234
235    /// Get the consumer's name
236    pub fn name(&self) -> Option<&str> {
237        self.name.as_deref()
238    }
239
240    /// Set the consumer's name
241    pub fn set_name(&mut self, name: impl Into<String>) {
242        self.name = Some(name.into());
243    }
244
245    /// Sequentially chain another readonly consumer
246    ///
247    /// Returns a new consumer that executes the current operation first, then the next operation. Consumes self.
248    ///
249    /// # Type Parameters
250    ///
251    /// * `C` - Type of the next consumer
252    ///
253    /// # Parameters
254    ///
255    /// * `next` - Consumer to execute after the current operation. **Note: This
256    ///   parameter is passed by value and will transfer ownership.** If you need
257    ///   to preserve the original consumer, clone it first (if it implements
258    ///   `Clone`). Can be:
259    ///   - A closure: `|x: &T|`
260    ///   - A `BoxReadonlyConsumer<T>`
261    ///   - An `RcReadonlyConsumer<T>`
262    ///   - An `ArcReadonlyConsumer<T>`
263    ///   - Any type implementing `ReadonlyConsumer<T>`
264    ///
265    /// # Returns
266    ///
267    /// Returns a new combined `BoxReadonlyConsumer<T>`
268    ///
269    /// # Examples
270    ///
271    /// ## Direct value passing (ownership transfer)
272    ///
273    /// ```rust
274    /// use prism3_function::{ReadonlyConsumer, BoxReadonlyConsumer};
275    ///
276    /// let first = BoxReadonlyConsumer::new(|x: &i32| {
277    ///     println!("First: {}", x);
278    /// });
279    /// let second = BoxReadonlyConsumer::new(|x: &i32| {
280    ///     println!("Second: {}", x);
281    /// });
282    ///
283    /// // second is moved here
284    /// let chained = first.and_then(second);
285    /// chained.accept(&5);
286    /// // second.accept(&3); // Would not compile - moved
287    /// ```
288    ///
289    /// ## Preserving original with clone
290    ///
291    /// ```rust
292    /// use prism3_function::{ReadonlyConsumer, BoxReadonlyConsumer, RcReadonlyConsumer};
293    ///
294    /// let first = BoxReadonlyConsumer::new(|x: &i32| {
295    ///     println!("First: {}", x);
296    /// });
297    /// let second = RcReadonlyConsumer::new(|x: &i32| {
298    ///     println!("Second: {}", x);
299    /// });
300    ///
301    /// // Clone to preserve original
302    /// let chained = first.and_then(second.clone());
303    /// chained.accept(&5);
304    ///
305    /// // Original still usable
306    /// second.accept(&3);
307    /// ```
308    pub fn and_then<C>(self, next: C) -> Self
309    where
310        C: ReadonlyConsumer<T> + 'static,
311    {
312        let first = self.function;
313        let second = next;
314        BoxReadonlyConsumer::new(move |t| {
315            first(t);
316            second.accept(t);
317        })
318    }
319
320    /// Create a no-op consumer
321    ///
322    /// # Returns
323    ///
324    /// Returns a no-op consumer
325    pub fn noop() -> Self {
326        BoxReadonlyConsumer::new(|_| {})
327    }
328}
329
330impl<T> ReadonlyConsumer<T> for BoxReadonlyConsumer<T> {
331    fn accept(&self, value: &T) {
332        (self.function)(value)
333    }
334
335    fn into_box(self) -> BoxReadonlyConsumer<T>
336    where
337        T: 'static,
338    {
339        self
340    }
341
342    fn into_rc(self) -> RcReadonlyConsumer<T>
343    where
344        T: 'static,
345    {
346        let func = self.function;
347        RcReadonlyConsumer::new(move |t| func(t))
348    }
349
350    fn into_arc(self) -> ArcReadonlyConsumer<T>
351    where
352        T: Send + Sync + 'static,
353    {
354        panic!("Cannot convert BoxReadonlyConsumer to ArcReadonlyConsumer: inner function may not be Send+Sync")
355    }
356
357    fn into_fn(self) -> impl Fn(&T)
358    where
359        T: 'static,
360    {
361        self.function
362    }
363}
364
365impl<T> fmt::Debug for BoxReadonlyConsumer<T> {
366    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367        f.debug_struct("BoxReadonlyConsumer")
368            .field("name", &self.name)
369            .field("function", &"<function>")
370            .finish()
371    }
372}
373
374impl<T> fmt::Display for BoxReadonlyConsumer<T> {
375    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
376        match &self.name {
377            Some(name) => write!(f, "BoxReadonlyConsumer({})", name),
378            None => write!(f, "BoxReadonlyConsumer"),
379        }
380    }
381}
382
383// ============================================================================
384// 3. ArcReadonlyConsumer - Thread-safe Shared Ownership Implementation
385// ============================================================================
386
387/// ArcReadonlyConsumer struct
388///
389/// Readonly consumer implementation based on `Arc<dyn Fn(&T) + Send + Sync>`,
390/// for thread-safe shared ownership scenarios. No Mutex needed because operations are readonly.
391///
392/// # Features
393///
394/// - **Shared Ownership**: Cloneable through `Arc`, allows multiple owners
395/// - **Thread Safe**: Implements `Send + Sync`, can be safely used concurrently
396/// - **Lock-free**: No Mutex protection needed because it's readonly
397/// - **Non-consuming API**: `and_then` borrows `&self`, original object remains usable
398///
399/// # Use Cases
400///
401/// Choose `ArcReadonlyConsumer` when:
402/// - Need to share readonly consumer across multiple threads
403/// - Pure observation operations, such as logging, monitoring, notifications
404/// - Need high-concurrency reads with no lock overhead
405///
406/// # Performance Advantages
407///
408/// Compared to `ArcConsumer`, `ArcReadonlyConsumer` has no Mutex lock overhead,
409/// performing better in high-concurrency scenarios.
410///
411/// # Examples
412///
413/// ```rust
414/// use prism3_function::{ReadonlyConsumer, ArcReadonlyConsumer};
415///
416/// let consumer = ArcReadonlyConsumer::new(|x: &i32| {
417///     println!("Observed: {}", x);
418/// });
419/// let clone = consumer.clone();
420///
421/// consumer.accept(&5);
422/// clone.accept(&10);
423/// ```
424///
425/// # Author
426///
427/// Hu Haixing
428pub struct ArcReadonlyConsumer<T> {
429    function: Arc<dyn Fn(&T) + Send + Sync>,
430    name: Option<String>,
431}
432
433impl<T> ArcReadonlyConsumer<T>
434where
435    T: Send + Sync + 'static,
436{
437    /// Create a new ArcReadonlyConsumer
438    ///
439    /// # Type Parameters
440    ///
441    /// * `F` - Closure type
442    ///
443    /// # Parameters
444    ///
445    /// * `f` - Closure to wrap
446    ///
447    /// # Returns
448    ///
449    /// Returns a new `ArcReadonlyConsumer<T>` instance
450    ///
451    /// # Examples
452    ///
453    /// ```rust
454    /// use prism3_function::{ReadonlyConsumer, ArcReadonlyConsumer};
455    ///
456    /// let consumer = ArcReadonlyConsumer::new(|x: &i32| {
457    ///     println!("Value: {}", x);
458    /// });
459    /// consumer.accept(&5);
460    /// ```
461    pub fn new<F>(f: F) -> Self
462    where
463        F: Fn(&T) + Send + Sync + 'static,
464    {
465        ArcReadonlyConsumer {
466            function: Arc::new(f),
467            name: None,
468        }
469    }
470
471    /// Get the consumer's name
472    pub fn name(&self) -> Option<&str> {
473        self.name.as_deref()
474    }
475
476    /// Set the consumer's name
477    pub fn set_name(&mut self, name: impl Into<String>) {
478        self.name = Some(name.into());
479    }
480
481    /// Convert to closure (without consuming self)
482    ///
483    /// Creates a new closure that calls the underlying function through Arc.
484    ///
485    /// # Returns
486    ///
487    /// Returns a closure implementing `Fn(&T)`
488    ///
489    /// # Examples
490    ///
491    /// ```rust
492    /// use prism3_function::{ReadonlyConsumer, ArcReadonlyConsumer};
493    ///
494    /// let consumer = ArcReadonlyConsumer::new(|x: &i32| {
495    ///     println!("Value: {}", x);
496    /// });
497    ///
498    /// let func = consumer.to_fn();
499    /// func(&5);
500    /// ```
501    pub fn to_fn(&self) -> impl Fn(&T)
502    where
503        T: 'static,
504    {
505        let func = Arc::clone(&self.function);
506        move |t: &T| {
507            func(t);
508        }
509    }
510
511    /// Sequentially chain another ArcReadonlyConsumer
512    ///
513    /// Returns a new consumer that executes the current operation first, then the next operation.
514    /// Borrows &self, does not consume the original consumer.
515    ///
516    /// # Parameters
517    ///
518    /// * `next` - Consumer to execute after the current operation. **Note: This
519    ///   parameter is passed by reference, so the original consumer remains
520    ///   usable.** Can be:
521    ///   - An `ArcReadonlyConsumer<T>` (passed by reference)
522    ///   - Any type implementing `ReadonlyConsumer<T> + Send + Sync`
523    ///
524    /// # Returns
525    ///
526    /// Returns a new combined `ArcReadonlyConsumer<T>`
527    ///
528    /// # Examples
529    ///
530    /// ```rust
531    /// use prism3_function::{ReadonlyConsumer, ArcReadonlyConsumer};
532    ///
533    /// let first = ArcReadonlyConsumer::new(|x: &i32| {
534    ///     println!("First: {}", x);
535    /// });
536    /// let second = ArcReadonlyConsumer::new(|x: &i32| {
537    ///     println!("Second: {}", x);
538    /// });
539    ///
540    /// // second is passed by reference, so it remains usable
541    /// let chained = first.and_then(&second);
542    ///
543    /// // first and second remain usable after chaining
544    /// chained.accept(&5);
545    /// first.accept(&3); // Still usable
546    /// second.accept(&7); // Still usable
547    /// ```
548    pub fn and_then(&self, next: &ArcReadonlyConsumer<T>) -> ArcReadonlyConsumer<T> {
549        let first = Arc::clone(&self.function);
550        let second = Arc::clone(&next.function);
551        ArcReadonlyConsumer {
552            function: Arc::new(move |t: &T| {
553                first(t);
554                second(t);
555            }),
556            name: None,
557        }
558    }
559}
560
561impl<T> ReadonlyConsumer<T> for ArcReadonlyConsumer<T> {
562    fn accept(&self, value: &T) {
563        (self.function)(value)
564    }
565
566    fn into_box(self) -> BoxReadonlyConsumer<T>
567    where
568        T: 'static,
569    {
570        let func = self.function;
571        BoxReadonlyConsumer::new(move |t| func(t))
572    }
573
574    fn into_rc(self) -> RcReadonlyConsumer<T>
575    where
576        T: 'static,
577    {
578        let func = self.function;
579        RcReadonlyConsumer::new(move |t| func(t))
580    }
581
582    fn into_arc(self) -> ArcReadonlyConsumer<T>
583    where
584        T: Send + Sync + 'static,
585    {
586        self
587    }
588
589    fn into_fn(self) -> impl Fn(&T)
590    where
591        T: 'static,
592    {
593        let func = self.function;
594        move |t: &T| {
595            func(t);
596        }
597    }
598}
599
600impl<T> Clone for ArcReadonlyConsumer<T> {
601    /// Clone ArcReadonlyConsumer
602    ///
603    /// Creates a new ArcReadonlyConsumer that shares the underlying function with the original instance.
604    fn clone(&self) -> Self {
605        Self {
606            function: Arc::clone(&self.function),
607            name: self.name.clone(),
608        }
609    }
610}
611
612impl<T> fmt::Debug for ArcReadonlyConsumer<T> {
613    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
614        f.debug_struct("ArcReadonlyConsumer")
615            .field("name", &self.name)
616            .field("function", &"<function>")
617            .finish()
618    }
619}
620
621impl<T> fmt::Display for ArcReadonlyConsumer<T> {
622    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
623        match &self.name {
624            Some(name) => write!(f, "ArcReadonlyConsumer({})", name),
625            None => write!(f, "ArcReadonlyConsumer"),
626        }
627    }
628}
629
630// ============================================================================
631// 4. RcReadonlyConsumer - Single-threaded Shared Ownership Implementation
632// ============================================================================
633
634/// RcReadonlyConsumer struct
635///
636/// Readonly consumer implementation based on `Rc<dyn Fn(&T)>` for single-threaded shared ownership scenarios.
637/// No RefCell needed because operations are readonly.
638///
639/// # Features
640///
641/// - **Shared Ownership**: Cloneable through `Rc`, allows multiple owners
642/// - **Single-threaded**: Not thread-safe, cannot be sent across threads
643/// - **No Interior Mutability Overhead**: No RefCell needed because it's readonly
644/// - **Non-consuming API**: `and_then` borrows `&self`, original object remains usable
645///
646/// # Use Cases
647///
648/// Choose `RcReadonlyConsumer` when:
649/// - Need to share readonly consumer within a single thread
650/// - Pure observation operations, performance critical
651/// - Event handling in single-threaded UI frameworks
652///
653/// # Performance Advantages
654///
655/// `RcReadonlyConsumer` has neither Arc's atomic operation overhead nor RefCell's
656/// runtime borrow checking overhead, making it the most performant of the three readonly consumers.
657///
658/// # Examples
659///
660/// ```rust
661/// use prism3_function::{ReadonlyConsumer, RcReadonlyConsumer};
662///
663/// let consumer = RcReadonlyConsumer::new(|x: &i32| {
664///     println!("Observed: {}", x);
665/// });
666/// let clone = consumer.clone();
667///
668/// consumer.accept(&5);
669/// clone.accept(&10);
670/// ```
671///
672/// # Author
673///
674/// Hu Haixing
675pub struct RcReadonlyConsumer<T> {
676    function: Rc<dyn Fn(&T)>,
677    name: Option<String>,
678}
679
680impl<T> RcReadonlyConsumer<T>
681where
682    T: 'static,
683{
684    /// Create a new RcReadonlyConsumer
685    ///
686    /// # Type Parameters
687    ///
688    /// * `F` - Closure type
689    ///
690    /// # Parameters
691    ///
692    /// * `f` - Closure to wrap
693    ///
694    /// # Returns
695    ///
696    /// Returns a new `RcReadonlyConsumer<T>` instance
697    ///
698    /// # Examples
699    ///
700    /// ```rust
701    /// use prism3_function::{ReadonlyConsumer, RcReadonlyConsumer};
702    ///
703    /// let consumer = RcReadonlyConsumer::new(|x: &i32| {
704    ///     println!("Value: {}", x);
705    /// });
706    /// consumer.accept(&5);
707    /// ```
708    pub fn new<F>(f: F) -> Self
709    where
710        F: Fn(&T) + 'static,
711    {
712        RcReadonlyConsumer {
713            function: Rc::new(f),
714            name: None,
715        }
716    }
717
718    /// Get the consumer's name
719    pub fn name(&self) -> Option<&str> {
720        self.name.as_deref()
721    }
722
723    /// Set the consumer's name
724    pub fn set_name(&mut self, name: impl Into<String>) {
725        self.name = Some(name.into());
726    }
727
728    /// Convert to closure (without consuming self)
729    ///
730    /// Creates a new closure that calls the underlying function through Rc.
731    ///
732    /// # Returns
733    ///
734    /// Returns a closure implementing `Fn(&T)`
735    ///
736    /// # Examples
737    ///
738    /// ```rust
739    /// use prism3_function::{ReadonlyConsumer, RcReadonlyConsumer};
740    ///
741    /// let consumer = RcReadonlyConsumer::new(|x: &i32| {
742    ///     println!("Value: {}", x);
743    /// });
744    ///
745    /// let func = consumer.to_fn();
746    /// func(&5);
747    /// ```
748    pub fn to_fn(&self) -> impl Fn(&T)
749    where
750        T: 'static,
751    {
752        let func = Rc::clone(&self.function);
753        move |t: &T| {
754            func(t);
755        }
756    }
757
758    /// Sequentially chain another RcReadonlyConsumer
759    ///
760    /// Returns a new consumer that executes the current operation first, then the next operation.
761    /// Borrows &self, does not consume the original consumer.
762    ///
763    /// # Parameters
764    ///
765    /// * `next` - Consumer to execute after the current operation. **Note: This
766    ///   parameter is passed by reference, so the original consumer remains
767    ///   usable.** Can be:
768    ///   - An `RcReadonlyConsumer<T>` (passed by reference)
769    ///   - Any type implementing `ReadonlyConsumer<T>`
770    ///
771    /// # Returns
772    ///
773    /// Returns a new combined `RcReadonlyConsumer<T>`
774    ///
775    /// # Examples
776    ///
777    /// ```rust
778    /// use prism3_function::{ReadonlyConsumer, RcReadonlyConsumer};
779    ///
780    /// let first = RcReadonlyConsumer::new(|x: &i32| {
781    ///     println!("First: {}", x);
782    /// });
783    /// let second = RcReadonlyConsumer::new(|x: &i32| {
784    ///     println!("Second: {}", x);
785    /// });
786    ///
787    /// // second is passed by reference, so it remains usable
788    /// let chained = first.and_then(&second);
789    ///
790    /// // first and second remain usable after chaining
791    /// chained.accept(&5);
792    /// first.accept(&3); // Still usable
793    /// second.accept(&7); // Still usable
794    /// ```
795    pub fn and_then(&self, next: &RcReadonlyConsumer<T>) -> RcReadonlyConsumer<T> {
796        let first = Rc::clone(&self.function);
797        let second = Rc::clone(&next.function);
798        RcReadonlyConsumer {
799            function: Rc::new(move |t: &T| {
800                first(t);
801                second(t);
802            }),
803            name: None,
804        }
805    }
806}
807
808impl<T> ReadonlyConsumer<T> for RcReadonlyConsumer<T> {
809    fn accept(&self, value: &T) {
810        (self.function)(value)
811    }
812
813    fn into_box(self) -> BoxReadonlyConsumer<T>
814    where
815        T: 'static,
816    {
817        let func = self.function;
818        BoxReadonlyConsumer::new(move |t| func(t))
819    }
820
821    fn into_rc(self) -> RcReadonlyConsumer<T>
822    where
823        T: 'static,
824    {
825        self
826    }
827
828    fn into_arc(self) -> ArcReadonlyConsumer<T>
829    where
830        T: Send + Sync + 'static,
831    {
832        panic!("Cannot convert RcReadonlyConsumer to ArcReadonlyConsumer (not Send+Sync)")
833    }
834
835    fn into_fn(self) -> impl Fn(&T)
836    where
837        T: 'static,
838    {
839        let func = self.function;
840        move |t: &T| {
841            func(t);
842        }
843    }
844}
845
846impl<T> Clone for RcReadonlyConsumer<T> {
847    /// Clone RcReadonlyConsumer
848    ///
849    /// Creates a new RcReadonlyConsumer that shares the underlying function with the original instance.
850    fn clone(&self) -> Self {
851        Self {
852            function: Rc::clone(&self.function),
853            name: self.name.clone(),
854        }
855    }
856}
857
858impl<T> fmt::Debug for RcReadonlyConsumer<T> {
859    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
860        f.debug_struct("RcReadonlyConsumer")
861            .field("name", &self.name)
862            .field("function", &"<function>")
863            .finish()
864    }
865}
866
867impl<T> fmt::Display for RcReadonlyConsumer<T> {
868    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
869        match &self.name {
870            Some(name) => write!(f, "RcReadonlyConsumer({})", name),
871            None => write!(f, "RcReadonlyConsumer"),
872        }
873    }
874}
875
876// ============================================================================
877// 5. Implement ReadonlyConsumer trait for closures
878// ============================================================================
879
880/// Implement ReadonlyConsumer for all Fn(&T)
881impl<T, F> ReadonlyConsumer<T> for F
882where
883    F: Fn(&T),
884{
885    fn accept(&self, value: &T) {
886        self(value)
887    }
888
889    fn into_box(self) -> BoxReadonlyConsumer<T>
890    where
891        Self: Sized + 'static,
892        T: 'static,
893    {
894        BoxReadonlyConsumer::new(self)
895    }
896
897    fn into_rc(self) -> RcReadonlyConsumer<T>
898    where
899        Self: Sized + 'static,
900        T: 'static,
901    {
902        RcReadonlyConsumer::new(self)
903    }
904
905    fn into_arc(self) -> ArcReadonlyConsumer<T>
906    where
907        Self: Sized + Send + Sync + 'static,
908        T: Send + Sync + 'static,
909    {
910        ArcReadonlyConsumer::new(self)
911    }
912
913    fn into_fn(self) -> impl Fn(&T)
914    where
915        Self: Sized + 'static,
916        T: 'static,
917    {
918        self
919    }
920}
921
922// ============================================================================
923// 6. Provide extension methods for closures
924// ============================================================================
925
926/// Extension trait providing readonly consumer composition methods for closures
927///
928/// Provides `and_then` and other composition methods for all closures implementing `Fn(&T)`,
929/// allowing closures to directly chain methods without explicit wrapper types.
930///
931/// # Features
932///
933/// - **Natural Syntax**: Chain operations directly on closures
934/// - **Returns BoxReadonlyConsumer**: Combined results can continue chaining
935/// - **Zero Cost**: No overhead when composing closures
936/// - **Auto-implementation**: All `Fn(&T)` closures automatically get these methods
937///
938/// # Examples
939///
940/// ```rust
941/// use prism3_function::{ReadonlyConsumer, FnReadonlyConsumerOps};
942///
943/// let chained = (|x: &i32| {
944///     println!("First: {}", x);
945/// }).and_then(|x: &i32| {
946///     println!("Second: {}", x);
947/// });
948/// chained.accept(&5);
949/// ```
950///
951/// # Author
952///
953/// Hu Haixing
954pub trait FnReadonlyConsumerOps<T>: Fn(&T) + Sized {
955    /// Sequentially chain another readonly consumer
956    ///
957    /// Returns a new consumer that executes the current operation first, then the next operation.
958    /// Consumes the current closure and returns `BoxReadonlyConsumer<T>`.
959    ///
960    /// # Type Parameters
961    ///
962    /// * `C` - Type of the next consumer
963    ///
964    /// # Parameters
965    ///
966    /// * `next` - Consumer to execute after the current operation
967    ///
968    /// # Returns
969    ///
970    /// Returns a combined `BoxReadonlyConsumer<T>`
971    ///
972    /// # Examples
973    ///
974    /// ```rust
975    /// use prism3_function::{ReadonlyConsumer, FnReadonlyConsumerOps};
976    ///
977    /// let chained = (|x: &i32| {
978    ///     println!("First: {}", x);
979    /// }).and_then(|x: &i32| {
980    ///     println!("Second: {}", x);
981    /// }).and_then(|x: &i32| println!("Third: {}", x));
982    ///
983    /// chained.accept(&5);
984    /// ```
985    fn and_then<C>(self, next: C) -> BoxReadonlyConsumer<T>
986    where
987        Self: 'static,
988        C: ReadonlyConsumer<T> + 'static,
989        T: 'static,
990    {
991        let first = self;
992        let second = next;
993        BoxReadonlyConsumer::new(move |t| {
994            first(t);
995            second.accept(t);
996        })
997    }
998}
999
1000/// Implement FnReadonlyConsumerOps for all closure types
1001impl<T, F> FnReadonlyConsumerOps<T> for F where F: Fn(&T) {}