prism3_function/transformers/
stateful_transformer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # StatefulTransformer Types
10//!
11//! Provides Rust implementations of stateful transformer traits for stateful value
12//! transformation. StatefulTransformers consume input values (taking ownership) and
13//! produce output values while allowing internal state modification. This is
14//! analogous to `FnMut(T) -> R` in Rust's standard library.
15//!
16//! This module provides the `StatefulTransformer<T, R>` trait and three implementations:
17//!
18//! - [`BoxStatefulTransformer`]: Single ownership, not cloneable
19//! - [`ArcStatefulTransformer`]: Thread-safe shared ownership, cloneable
20//! - [`RcStatefulTransformer`]: Single-threaded shared ownership, cloneable
21//!
22//! # Author
23//!
24//! Haixing Hu
25use std::cell::RefCell;
26use std::rc::Rc;
27use std::sync::Arc;
28
29use parking_lot::Mutex;
30
31use crate::macros::{
32    impl_arc_conversions,
33    impl_box_conversions,
34    impl_closure_trait,
35    impl_rc_conversions,
36};
37use crate::predicates::predicate::{
38    ArcPredicate,
39    BoxPredicate,
40    Predicate,
41    RcPredicate,
42};
43use crate::transformers::{
44    macros::{
45        impl_box_conditional_transformer,
46        impl_box_transformer_methods,
47        impl_conditional_transformer_clone,
48        impl_conditional_transformer_debug_display,
49        impl_shared_conditional_transformer,
50        impl_shared_transformer_methods,
51        impl_transformer_clone,
52        impl_transformer_common_methods,
53        impl_transformer_constant_method,
54        impl_transformer_debug_display,
55    },
56    transformer_once::BoxTransformerOnce,
57};
58
59// ============================================================================
60// Core Trait
61// ============================================================================
62
63/// StatefulTransformer trait - transforms values from type T to type R with state
64///
65/// Defines the behavior of a stateful transformation: converting a value
66/// of type `T` to a value of type `R` by consuming the input while
67/// allowing modification of internal state. This is analogous to
68/// `FnMut(T) -> R` in Rust's standard library.
69///
70/// # Type Parameters
71///
72/// * `T` - The type of the input value (consumed)
73/// * `R` - The type of the output value
74///
75/// # Author
76///
77/// Haixing Hu
78pub trait StatefulTransformer<T, R> {
79    /// Applies the transformation to the input value to produce an output value
80    ///
81    /// # Parameters
82    ///
83    /// * `input` - The input value to transform (consumed)
84    ///
85    /// # Returns
86    ///
87    /// The transformed output value
88    fn apply(&mut self, input: T) -> R;
89
90    /// Converts to BoxStatefulTransformer
91    ///
92    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
93    /// after calling this method.
94    ///
95    /// # Returns
96    ///
97    /// Returns `BoxStatefulTransformer<T, R>`
98    ///
99    /// # Default Implementation
100    ///
101    /// The default implementation wraps `self` in a `BoxStatefulTransformer` by creating
102    /// a new closure that calls `self.apply()`. This provides a zero-cost
103    /// abstraction for most use cases.
104    ///
105    /// # Examples
106    ///
107    /// ```rust
108    /// use prism3_function::{StatefulTransformer, BoxStatefulTransformer};
109    ///
110    /// struct CustomTransformer {
111    ///     multiplier: i32,
112    /// }
113    ///
114    /// impl StatefulTransformer<i32, i32> for CustomTransformer {
115    ///     fn apply(&mut self, input: i32) -> i32 {
116    ///         self.multiplier += 1;
117    ///         input * self.multiplier
118    ///     }
119    /// }
120    ///
121    /// let transformer = CustomTransformer { multiplier: 0 };
122    /// let mut boxed = transformer.into_box();
123    /// assert_eq!(boxed.apply(10), 10);  // 10 * 1
124    /// assert_eq!(boxed.apply(10), 20);  // 10 * 2
125    /// ```
126    fn into_box(self) -> BoxStatefulTransformer<T, R>
127    where
128        Self: Sized + 'static,
129        T: 'static,
130        R: 'static,
131    {
132        let mut transformer = self;
133        BoxStatefulTransformer::new(move |t| transformer.apply(t))
134    }
135
136    /// Converts to RcStatefulTransformer
137    ///
138    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
139    /// after calling this method.
140    ///
141    /// # Returns
142    ///
143    /// Returns `RcStatefulTransformer<T, R>`
144    ///
145    /// # Default Implementation
146    ///
147    /// The default implementation first converts to `BoxStatefulTransformer` using
148    /// `into_box()`, then wraps it in `RcStatefulTransformer`. Specific implementations
149    /// may override this for better efficiency.
150    ///
151    /// # Examples
152    ///
153    /// ```rust
154    /// use prism3_function::{StatefulTransformer, RcStatefulTransformer};
155    ///
156    /// struct CustomTransformer {
157    ///     multiplier: i32,
158    /// }
159    ///
160    /// impl StatefulTransformer<i32, i32> for CustomTransformer {
161    ///     fn apply(&mut self, input: i32) -> i32 {
162    ///         self.multiplier += 1;
163    ///         input * self.multiplier
164    ///     }
165    /// }
166    ///
167    /// let transformer = CustomTransformer { multiplier: 0 };
168    /// let mut rc_transformer = transformer.into_rc();
169    /// assert_eq!(rc_transformer.apply(10), 10);  // 10 * 1
170    /// assert_eq!(rc_transformer.apply(10), 20);  // 10 * 2
171    /// ```
172    fn into_rc(self) -> RcStatefulTransformer<T, R>
173    where
174        Self: Sized + 'static,
175        T: 'static,
176        R: 'static,
177    {
178        let mut transformer = self;
179        RcStatefulTransformer::new(move |t| transformer.apply(t))
180    }
181
182    /// Converts to ArcStatefulTransformer
183    ///
184    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
185    /// after calling this method.
186    ///
187    /// # Returns
188    ///
189    /// Returns `ArcStatefulTransformer<T, R>`
190    ///
191    /// # Default Implementation
192    ///
193    /// The default implementation wraps `self` in an `ArcStatefulTransformer` by creating
194    /// a new closure that calls `self.apply()`. Note that this requires `self`
195    /// to implement `Send` due to Arc's thread-safety requirements.
196    ///
197    /// # Examples
198    ///
199    /// ```rust
200    /// use prism3_function::{StatefulTransformer, ArcStatefulTransformer};
201    ///
202    /// struct CustomTransformer {
203    ///     multiplier: i32,
204    /// }
205    ///
206    /// impl StatefulTransformer<i32, i32> for CustomTransformer {
207    ///     fn apply(&mut self, input: i32) -> i32 {
208    ///         self.multiplier += 1;
209    ///         input * self.multiplier
210    ///     }
211    /// }
212    ///
213    /// let transformer = CustomTransformer { multiplier: 0 };
214    /// let mut arc_transformer = transformer.into_arc();
215    /// assert_eq!(arc_transformer.apply(10), 10);  // 10 * 1
216    /// assert_eq!(arc_transformer.apply(10), 20);  // 10 * 2
217    /// ```
218    fn into_arc(self) -> ArcStatefulTransformer<T, R>
219    where
220        Self: Sized + Send + 'static,
221        T: Send + Sync + 'static,
222        R: Send + 'static,
223    {
224        let mut transformer = self;
225        ArcStatefulTransformer::new(move |t| transformer.apply(t))
226    }
227
228    /// Converts to a closure implementing `FnMut(T) -> R`
229    ///
230    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
231    /// after calling this method.
232    ///
233    /// # Returns
234    ///
235    /// Returns an implementation of `FnMut(T) -> R`
236    ///
237    /// # Default Implementation
238    ///
239    /// The default implementation creates a new closure that calls `self.apply()`.
240    /// Specific implementations may override this for better efficiency.
241    ///
242    /// # Examples
243    ///
244    /// ```rust
245    /// use prism3_function::{StatefulTransformer, BoxStatefulTransformer};
246    ///
247    /// let transformer = BoxStatefulTransformer::new(|x: i32| x * 2);
248    /// let mut closure = transformer.into_fn();
249    /// assert_eq!(closure(10), 20);
250    /// assert_eq!(closure(15), 30);
251    /// ```
252    fn into_fn(self) -> impl FnMut(T) -> R
253    where
254        Self: Sized + 'static,
255        T: 'static,
256        R: 'static,
257    {
258        let mut transformer = self;
259        move |t| transformer.apply(t)
260    }
261
262    /// Converts to `BoxTransformerOnce`.
263    ///
264    /// This method has a default implementation that wraps the
265    /// transformer in a `BoxTransformerOnce`. Custom implementations
266    /// can override this method for optimization purposes.
267    ///
268    /// # Returns
269    ///
270    /// A new `BoxTransformerOnce<T, R>` instance
271    ///
272    /// # Examples
273    ///
274    /// ```rust
275    /// use prism3_function::StatefulTransformer;
276    ///
277    /// let closure = |x: i32| x * 2;
278    /// let once = closure.into_once();
279    /// assert_eq!(once.apply(5), 10);
280    /// ```
281    fn into_once(self) -> BoxTransformerOnce<T, R>
282    where
283        Self: Sized + 'static,
284        T: 'static,
285        R: 'static,
286    {
287        let mut transformer = self;
288        BoxTransformerOnce::new(move |t| transformer.apply(t))
289    }
290
291    /// Non-consuming conversion to `BoxStatefulTransformer`.
292    ///
293    /// Default implementation requires `Self: Clone` and wraps a cloned
294    /// instance in a `RefCell` so the returned transformer can mutate state
295    /// across calls.
296    fn to_box(&self) -> BoxStatefulTransformer<T, R>
297    where
298        Self: Sized + Clone + 'static,
299        T: 'static,
300        R: 'static,
301    {
302        self.clone().into_box()
303    }
304
305    /// Non-consuming conversion to `RcStatefulTransformer`.
306    ///
307    /// Default implementation clones `self` into an `Rc<RefCell<_>>` so the
308    /// resulting transformer can be shared within a single thread.
309    fn to_rc(&self) -> RcStatefulTransformer<T, R>
310    where
311        Self: Sized + Clone + 'static,
312        T: 'static,
313        R: 'static,
314    {
315        self.clone().into_rc()
316    }
317
318    /// Non-consuming conversion to `ArcStatefulTransformer` (thread-safe).
319    ///
320    /// Default implementation requires `Self: Clone + Send + Sync` and wraps
321    /// the cloned instance in `Arc<Mutex<_>>` so it can be used across
322    /// threads.
323    fn to_arc(&self) -> ArcStatefulTransformer<T, R>
324    where
325        Self: Sized + Clone + Send + Sync + 'static,
326        T: Send + Sync + 'static,
327        R: Send + 'static,
328    {
329        self.clone().into_arc()
330    }
331
332    /// Non-consuming conversion to a closure (`FnMut(T) -> R`).
333    ///
334    /// Default implementation clones `self` into a `RefCell` and returns a
335    /// closure that calls `apply` on the interior mutable value.
336    fn to_fn(&self) -> impl FnMut(T) -> R
337    where
338        Self: Sized + Clone + 'static,
339        T: 'static,
340        R: 'static,
341    {
342        self.clone().into_fn()
343    }
344
345    /// Creates a `BoxTransformerOnce` from a cloned transformer
346    ///
347    /// Uses `Clone` to obtain an owned copy and converts it into a
348    /// `BoxTransformerOnce`. Requires `Self: Clone`. Custom implementations
349    /// can override this for better performance.
350    fn to_once(&self) -> BoxTransformerOnce<T, R>
351    where
352        Self: Sized + Clone + 'static,
353        T: 'static,
354        R: 'static,
355    {
356        self.clone().into_once()
357    }
358}
359
360// ============================================================================
361// BoxStatefulTransformer - Box<dyn FnMut(T) -> R>
362// ============================================================================
363
364/// BoxStatefulTransformer - transformer wrapper based on `Box<dyn FnMut>`
365///
366/// A transformer wrapper that provides single ownership with reusable stateful
367/// transformation. The transformer consumes the input and can be called
368/// multiple times while maintaining internal state.
369///
370/// # Features
371///
372/// - **Based on**: `Box<dyn FnMut(T) -> R>`
373/// - **Ownership**: Single ownership, cannot be cloned
374/// - **Reusability**: Can be called multiple times (each call consumes
375///   its input)
376/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
377/// - **Statefulness**: Can modify internal state between calls
378///
379/// # Author
380///
381/// Haixing Hu
382pub struct BoxStatefulTransformer<T, R> {
383    function: Box<dyn FnMut(T) -> R>,
384    name: Option<String>,
385}
386
387impl<T, R> BoxStatefulTransformer<T, R>
388where
389    T: 'static,
390    R: 'static,
391{
392    impl_transformer_common_methods!(
393        BoxStatefulTransformer<T, R>,
394        (FnMut(T) -> R + 'static),
395        |f| Box::new(f)
396    );
397
398    impl_box_transformer_methods!(
399        BoxStatefulTransformer<T, R>,
400        BoxConditionalStatefulTransformer,
401        StatefulTransformer
402    );
403}
404
405// Implement constant method for BoxStatefulTransformer
406impl_transformer_constant_method!(stateful BoxStatefulTransformer<T, R>);
407
408// Implement Debug and Display for BoxStatefulTransformer
409impl_transformer_debug_display!(BoxStatefulTransformer<T, R>);
410
411// Implement StatefulTransformer trait for BoxStatefulTransformer
412impl<T, R> StatefulTransformer<T, R> for BoxStatefulTransformer<T, R> {
413    fn apply(&mut self, input: T) -> R {
414        (self.function)(input)
415    }
416
417    // Generates: into_box(), into_rc(), into_fn(), into_once()
418    impl_box_conversions!(
419        BoxStatefulTransformer<T, R>,
420        RcStatefulTransformer,
421        FnMut(T) -> R,
422        BoxTransformerOnce
423    );
424
425    // do NOT override StatefulTransformer::to_xxx() because BoxStatefulTransformer is not Clone
426    // and calling BoxStatefulTransformer::to_xxx() will cause a compile error
427}
428
429// ============================================================================
430// RcStatefulTransformer - Rc<RefCell<dyn FnMut(T) -> R>>
431// ============================================================================
432
433/// RcStatefulTransformer - single-threaded transformer wrapper
434///
435/// A single-threaded, clonable transformer wrapper optimized for scenarios
436/// that require sharing without thread-safety overhead.
437///
438/// # Features
439///
440/// - **Based on**: `Rc<RefCell<dyn FnMut(T) -> R>>`
441/// - **Ownership**: Shared ownership via reference counting (non-atomic)
442/// - **Reusability**: Can be called multiple times (each call consumes
443///   its input)
444/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
445/// - **Clonable**: Cheap cloning via `Rc::clone`
446/// - **Statefulness**: Can modify internal state between calls
447///
448/// # Author
449///
450/// Haixing Hu
451pub struct RcStatefulTransformer<T, R> {
452    function: Rc<RefCell<dyn FnMut(T) -> R>>,
453    name: Option<String>,
454}
455
456// Implement RcStatefulTransformer
457impl<T, R> RcStatefulTransformer<T, R>
458where
459    T: 'static,
460    R: 'static,
461{
462    impl_transformer_common_methods!(
463        RcStatefulTransformer<T, R>,
464        (FnMut(T) -> R + 'static),
465        |f| Rc::new(RefCell::new(f))
466    );
467
468    impl_shared_transformer_methods!(
469        RcStatefulTransformer<T, R>,
470        RcConditionalStatefulTransformer,
471        into_rc,
472        StatefulTransformer,
473        'static
474    );
475}
476
477// Implement constant method for RcStatefulTransformer
478impl_transformer_constant_method!(stateful RcStatefulTransformer<T, R>);
479
480// Implement Debug and Display for RcStatefulTransformer
481impl_transformer_debug_display!(RcStatefulTransformer<T, R>);
482
483// Implement Clone for RcStatefulTransformer
484impl_transformer_clone!(RcStatefulTransformer<T, R>);
485
486// Implement StatefulTransformer trait for RcStatefulTransformer
487impl<T, R> StatefulTransformer<T, R> for RcStatefulTransformer<T, R> {
488    fn apply(&mut self, input: T) -> R {
489        let mut self_fn = self.function.borrow_mut();
490        self_fn(input)
491    }
492
493    // Generate all conversion methods using the unified macro
494    impl_rc_conversions!(
495        RcStatefulTransformer<T, R>,
496        BoxStatefulTransformer,
497        BoxTransformerOnce,
498        FnMut(input: T) -> R
499    );
500}
501
502// ============================================================================
503// ArcStatefulTransformer - Arc<Mutex<dyn FnMut(T) -> R + Send>>
504// ============================================================================
505
506/// ArcStatefulTransformer - thread-safe transformer wrapper
507///
508/// A thread-safe, clonable transformer wrapper suitable for multi-threaded
509/// scenarios. Can be called multiple times and shared across threads
510/// while maintaining internal state.
511///
512/// # Features
513///
514/// - **Based on**: `Arc<Mutex<dyn FnMut(T) -> R + Send>>`
515/// - **Ownership**: Shared ownership via reference counting
516/// - **Reusability**: Can be called multiple times (each call consumes
517///   its input)
518/// - **Thread Safety**: Thread-safe (`Send` required)
519/// - **Clonable**: Cheap cloning via `Arc::clone`
520/// - **Statefulness**: Can modify internal state between calls
521///
522/// # Author
523///
524/// Haixing Hu
525pub struct ArcStatefulTransformer<T, R> {
526    function: Arc<Mutex<dyn FnMut(T) -> R + Send>>,
527    name: Option<String>,
528}
529
530impl<T, R> ArcStatefulTransformer<T, R>
531where
532    T: 'static,
533    R: 'static,
534{
535    impl_transformer_common_methods!(
536        ArcStatefulTransformer<T, R>,
537        (FnMut(T) -> R + Send + 'static),
538        |f| Arc::new(Mutex::new(f))
539    );
540
541    impl_shared_transformer_methods!(
542        ArcStatefulTransformer<T, R>,
543        ArcConditionalStatefulTransformer,
544        into_arc,
545        StatefulTransformer,
546        Send + Sync + 'static
547    );
548}
549
550// Implement constant method for ArcStatefulTransformer
551impl_transformer_constant_method!(stateful thread_safe ArcStatefulTransformer<T, R>);
552
553// Implement Debug and Display for ArcStatefulTransformer
554impl_transformer_debug_display!(ArcStatefulTransformer<T, R>);
555
556// Implement Clone for ArcStatefulTransformer
557impl_transformer_clone!(ArcStatefulTransformer<T, R>);
558
559impl<T, R> StatefulTransformer<T, R> for ArcStatefulTransformer<T, R> {
560    fn apply(&mut self, input: T) -> R {
561        let mut func = self.function.lock();
562        func(input)
563    }
564
565    // Use macro to implement conversion methods
566    impl_arc_conversions!(
567        ArcStatefulTransformer<T, R>,
568        BoxStatefulTransformer,
569        RcStatefulTransformer,
570        BoxTransformerOnce,
571        FnMut(t: T) -> R
572    );
573}
574
575// ============================================================================
576// Blanket implementation for standard FnMut trait
577// ============================================================================
578
579// Implement StatefulTransformer<T, R> for any type that implements FnMut(T) -> R
580impl_closure_trait!(
581    StatefulTransformer<T, R>,
582    apply,
583    BoxTransformerOnce,
584    FnMut(input: T) -> R
585);
586
587// ============================================================================
588// FnStatefulTransformerOps - Extension trait for closure transformers
589// ============================================================================
590
591/// Extension trait for closures implementing `FnMut(T) -> R`
592///
593/// Provides composition methods (`and_then`, `compose`, `when`) for
594/// closures without requiring explicit wrapping in `BoxStatefulTransformer`,
595/// `RcStatefulTransformer`, or `ArcStatefulTransformer`.
596///
597/// This trait is automatically implemented for all closures that
598/// implement `FnMut(T) -> R`.
599///
600/// # Design Rationale
601///
602/// While closures automatically implement `StatefulTransformer<T, R>` through blanket
603/// implementation, they don't have access to instance methods like
604/// `and_then`, `compose`, and `when`. This extension trait provides
605/// those methods, returning `BoxStatefulTransformer` for maximum flexibility.
606///
607/// # Examples
608///
609/// ## Chain composition with and_then
610///
611/// ```rust
612/// use prism3_function::{StatefulTransformer, FnStatefulTransformerOps};
613///
614/// let mut counter1 = 0;
615/// let transformer1 = move |x: i32| {
616///     counter1 += 1;
617///     x + counter1
618/// };
619///
620/// let mut counter2 = 0;
621/// let transformer2 = move |x: i32| {
622///     counter2 += 1;
623///     x * counter2
624/// };
625///
626/// let mut composed = transformer1.and_then(transformer2);
627/// assert_eq!(composed.apply(10), 11);  // (10 + 1) * 1
628/// ```
629///
630/// ## Reverse composition with compose
631///
632/// ```rust
633/// use prism3_function::{StatefulTransformer, FnStatefulTransformerOps};
634///
635/// let mut counter = 0;
636/// let transformer = move |x: i32| {
637///     counter += 1;
638///     x * counter
639/// };
640///
641/// let mut composed = transformer.compose(|x: i32| x + 1);
642/// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
643/// ```
644///
645/// ## Conditional mapping with when
646///
647/// ```rust
648/// use prism3_function::{StatefulTransformer, FnStatefulTransformerOps};
649///
650/// let mut transformer = (|x: i32| x * 2)
651///     .when(|x: &i32| *x > 0)
652///     .or_else(|x: i32| -x);
653///
654/// assert_eq!(transformer.apply(5), 10);
655/// assert_eq!(transformer.apply(-5), 5);
656/// ```
657///
658/// # Author
659///
660/// Haixing Hu
661pub trait FnStatefulTransformerOps<T, R>: FnMut(T) -> R + Sized + 'static {
662    /// Chain composition - applies self first, then after
663    ///
664    /// Creates a new transformer that applies this transformer first, then applies
665    /// the after transformer to the result. Consumes self and returns a
666    /// `BoxStatefulTransformer`.
667    ///
668    /// # Type Parameters
669    ///
670    /// * `S` - The output type of the after transformer
671    /// * `F` - The type of the after transformer (must implement StatefulTransformer<R, S>)
672    ///
673    /// # Parameters
674    ///
675    /// * `after` - The transformer to apply after self. Can be:
676    ///   - A closure: `|x: R| -> S`
677    ///   - A `BoxStatefulTransformer<R, S>`
678    ///   - An `RcStatefulTransformer<R, S>`
679    ///   - An `ArcStatefulTransformer<R, S>`
680    ///   - Any type implementing `StatefulTransformer<R, S>`
681    ///
682    /// # Returns
683    ///
684    /// A new `BoxStatefulTransformer<T, S>` representing the composition
685    ///
686    /// # Examples
687    ///
688    /// ```rust
689    /// use prism3_function::{StatefulTransformer, FnStatefulTransformerOps, BoxStatefulTransformer};
690    ///
691    /// let mut counter1 = 0;
692    /// let transformer1 = move |x: i32| {
693    ///     counter1 += 1;
694    ///     x + counter1
695    /// };
696    ///
697    /// let mut counter2 = 0;
698    /// let transformer2 = BoxStatefulTransformer::new(move |x: i32| {
699    ///     counter2 += 1;
700    ///     x * counter2
701    /// });
702    ///
703    /// let mut composed = transformer1.and_then(transformer2);
704    /// assert_eq!(composed.apply(10), 11);
705    /// ```
706    fn and_then<S, F>(self, after: F) -> BoxStatefulTransformer<T, S>
707    where
708        S: 'static,
709        F: StatefulTransformer<R, S> + 'static,
710        T: 'static,
711        R: 'static,
712    {
713        BoxStatefulTransformer::new(self).and_then(after)
714    }
715
716    /// Creates a conditional transformer
717    ///
718    /// Returns a transformer that only executes when a predicate is satisfied.
719    /// You must call `or_else()` to provide an alternative transformer for
720    /// when the condition is not satisfied.
721    ///
722    /// # Parameters
723    ///
724    /// * `predicate` - The condition to check. Can be:
725    ///   - A closure: `|x: &T| -> bool`
726    ///   - A function pointer: `fn(&T) -> bool`
727    ///   - A `BoxPredicate<T>`
728    ///   - An `RcPredicate<T>`
729    ///   - An `ArcPredicate<T>`
730    ///   - Any type implementing `Predicate<T>`
731    ///
732    /// # Returns
733    ///
734    /// Returns `BoxConditionalStatefulTransformer<T, R>`
735    ///
736    /// # Examples
737    ///
738    /// ```rust
739    /// use prism3_function::{StatefulTransformer, FnStatefulTransformerOps};
740    ///
741    /// let mut transformer = (|x: i32| x * 2)
742    ///     .when(|x: &i32| *x > 0)
743    ///     .or_else(|x: i32| -x);
744    ///
745    /// assert_eq!(transformer.apply(5), 10);
746    /// assert_eq!(transformer.apply(-5), 5);
747    /// ```
748    fn when<P>(self, predicate: P) -> BoxConditionalStatefulTransformer<T, R>
749    where
750        P: Predicate<T> + 'static,
751        T: 'static,
752        R: 'static,
753    {
754        BoxStatefulTransformer::new(self).when(predicate)
755    }
756}
757
758/// Blanket implementation of FnStatefulTransformerOps for all closures
759///
760/// Automatically implements `FnStatefulTransformerOps<T, R>` for any type that
761/// implements `FnMut(T) -> R`.
762///
763/// # Author
764///
765/// Haixing Hu
766impl<T, R, F> FnStatefulTransformerOps<T, R> for F where F: FnMut(T) -> R + 'static {}
767
768// ============================================================================
769// BoxConditionalStatefulTransformer - Box-based Conditional StatefulTransformer
770// ============================================================================
771
772/// BoxConditionalStatefulTransformer struct
773///
774/// A conditional transformer that only executes when a predicate is satisfied.
775/// Uses `BoxStatefulTransformer` and `BoxPredicate` for single ownership semantics.
776///
777/// This type is typically created by calling `BoxStatefulTransformer::when()` and is
778/// designed to work with the `or_else()` method to create if-then-else
779/// logic.
780///
781/// # Features
782///
783/// - **Single Ownership**: Not cloneable, consumes `self` on use
784/// - **Conditional Execution**: Only maps when predicate returns `true`
785/// - **Chainable**: Can add `or_else` branch to create if-then-else
786///   logic
787/// - **Implements StatefulTransformer**: Can be used anywhere a `StatefulTransformer` is expected
788///
789/// # Examples
790///
791/// ```rust
792/// use prism3_function::{StatefulTransformer, BoxStatefulTransformer};
793///
794/// let mut high_count = 0;
795/// let mut low_count = 0;
796///
797/// let mut transformer = BoxStatefulTransformer::new(move |x: i32| {
798///     high_count += 1;
799///     x * 2
800/// })
801/// .when(|x: &i32| *x >= 10)
802/// .or_else(move |x| {
803///     low_count += 1;
804///     x + 1
805/// });
806///
807/// assert_eq!(transformer.apply(15), 30); // when branch executed
808/// assert_eq!(transformer.apply(5), 6);   // or_else branch executed
809/// ```
810///
811/// # Author
812///
813/// Haixing Hu
814pub struct BoxConditionalStatefulTransformer<T, R> {
815    transformer: BoxStatefulTransformer<T, R>,
816    predicate: BoxPredicate<T>,
817}
818
819// Implement BoxConditionalTransformer
820impl_box_conditional_transformer!(
821    BoxConditionalStatefulTransformer<T, R>,
822    BoxStatefulTransformer,
823    StatefulTransformer
824);
825
826// Use macro to generate Debug and Display implementations
827impl_conditional_transformer_debug_display!(BoxConditionalStatefulTransformer<T, R>);
828
829// ============================================================================
830// RcConditionalStatefulTransformer - Rc-based Conditional StatefulTransformer
831// ============================================================================
832
833/// RcConditionalStatefulTransformer struct
834///
835/// A single-threaded conditional transformer that only executes when a
836/// predicate is satisfied. Uses `RcStatefulTransformer` and `RcPredicate` for shared
837/// ownership within a single thread.
838///
839/// This type is typically created by calling `RcStatefulTransformer::when()` and is
840/// designed to work with the `or_else()` method to create if-then-else
841/// logic.
842///
843/// # Features
844///
845/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
846/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
847/// - **Conditional Execution**: Only maps when predicate returns `true`
848/// - **No Lock Overhead**: More efficient than `ArcConditionalStatefulTransformer`
849///
850/// # Examples
851///
852/// ```rust
853/// use prism3_function::{StatefulTransformer, RcStatefulTransformer};
854///
855/// let mut transformer = RcStatefulTransformer::new(|x: i32| x * 2)
856///     .when(|x: &i32| *x > 0)
857///     .or_else(|x: i32| -x);
858///
859/// let mut transformer_clone = transformer.clone();
860///
861/// assert_eq!(transformer.apply(5), 10);
862/// assert_eq!(transformer_clone.apply(-5), 5);
863/// ```
864///
865/// # Author
866///
867/// Haixing Hu
868pub struct RcConditionalStatefulTransformer<T, R> {
869    transformer: RcStatefulTransformer<T, R>,
870    predicate: RcPredicate<T>,
871}
872
873// Implement RcConditionalStatefulTransformer
874impl_shared_conditional_transformer!(
875    RcConditionalStatefulTransformer<T, R>,
876    RcStatefulTransformer,
877    StatefulTransformer,
878    into_rc,
879    'static
880);
881
882// Use macro to generate Debug and Display implementations
883impl_conditional_transformer_debug_display!(RcConditionalStatefulTransformer<T, R>);
884
885// Implement Clone for RcConditionalStatefulTransformer
886impl_conditional_transformer_clone!(RcConditionalStatefulTransformer<T, R>);
887
888// ============================================================================
889// ArcConditionalStatefulTransformer - Arc-based Conditional StatefulTransformer
890// ============================================================================
891
892/// ArcConditionalStatefulTransformer struct
893///
894/// A thread-safe conditional transformer that only executes when a predicate
895/// is satisfied. Uses `ArcStatefulTransformer` and `ArcPredicate` for shared
896/// ownership across threads.
897///
898/// This type is typically created by calling `ArcStatefulTransformer::when()` and is
899/// designed to work with the `or_else()` method to create if-then-else
900/// logic.
901///
902/// # Features
903///
904/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
905/// - **Thread-Safe**: Implements `Send`, safe for concurrent use
906/// - **Conditional Execution**: Only maps when predicate returns `true`
907/// - **Chainable**: Can add `or_else` branch to create if-then-else
908///   logic
909///
910/// # Examples
911///
912/// ```rust
913/// use prism3_function::{StatefulTransformer, ArcStatefulTransformer};
914///
915/// let mut transformer = ArcStatefulTransformer::new(|x: i32| x * 2)
916///     .when(|x: &i32| *x > 0)
917///     .or_else(|x: i32| -x);
918///
919/// let mut transformer_clone = transformer.clone();
920///
921/// assert_eq!(transformer.apply(5), 10);
922/// assert_eq!(transformer_clone.apply(-5), 5);
923/// ```
924///
925/// # Author
926///
927/// Haixing Hu
928pub struct ArcConditionalStatefulTransformer<T, R> {
929    transformer: ArcStatefulTransformer<T, R>,
930    predicate: ArcPredicate<T>,
931}
932
933// Implement ArcConditionalStatefulTransformer
934impl_shared_conditional_transformer!(
935    ArcConditionalStatefulTransformer<T, R>,
936    ArcStatefulTransformer,
937    StatefulTransformer,
938    into_arc,
939    Send + Sync + 'static
940);
941
942// Use macro to generate Debug and Display implementations
943impl_conditional_transformer_debug_display!(ArcConditionalStatefulTransformer<T, R>);
944
945// Implement Clone for ArcConditionalStatefulTransformer
946impl_conditional_transformer_clone!(ArcConditionalStatefulTransformer<T, R>);