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