prism3_function/transformers/
stateful_bi_transformer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # StatefulBiTransformer Types
10//!
11//! Provides Rust implementations of stateful bi-transformer traits for type
12//! conversion and value transformation with two inputs. StatefulBiTransformers
13//! consume two input values (taking ownership) and produce an output value.
14//!
15//! This module provides the `StatefulBiTransformer<T, U, R>` trait and three
16//! implementations:
17//!
18//! - [`BoxStatefulBiTransformer`]: Single ownership, not cloneable
19//! - [`ArcStatefulBiTransformer`]: Thread-safe shared ownership, cloneable
20//! - [`RcStatefulBiTransformer`]: 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_closure_trait,
34    impl_rc_conversions,
35};
36use crate::predicates::bi_predicate::{
37    ArcBiPredicate,
38    BiPredicate,
39    BoxBiPredicate,
40    RcBiPredicate,
41};
42use crate::transformers::{
43    bi_transformer_once::BoxBiTransformerOnce,
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    stateful_transformer::StatefulTransformer,
57};
58
59// ============================================================================
60// Core Trait
61// ============================================================================
62
63/// StatefulBiTransformer trait - transforms two values to produce a result
64///
65/// Defines the behavior of a bi-transformation: converting two values of types
66/// `T` and `U` to a value of type `R` by consuming the inputs. This is
67/// analogous to `Fn(T, U) -> R` in Rust's standard library.
68///
69/// # Type Parameters
70///
71/// * `T` - The type of the first input value (consumed)
72/// * `U` - The type of the second input value (consumed)
73/// * `R` - The type of the output value
74///
75/// # Author
76///
77/// Haixing Hu
78pub trait StatefulBiTransformer<T, U, R> {
79    /// Transforms two input values to produce an output value
80    ///
81    /// # Parameters
82    ///
83    /// * `first` - The first input value to transform (consumed)
84    /// * `second` - The second input value to transform (consumed)
85    ///
86    /// # Returns
87    ///
88    /// The transformed output value
89    fn apply(&mut self, first: T, second: U) -> R;
90
91    /// Converts to BoxStatefulBiTransformer
92    ///
93    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
94    /// after calling this method.
95    ///
96    /// # Default Implementation
97    ///
98    /// The default implementation wraps `self` in a `Box` and creates a
99    /// `BoxStatefulBiTransformer`. Types can override this method to provide more
100    /// efficient conversions.
101    ///
102    /// # Returns
103    ///
104    /// Returns `BoxStatefulBiTransformer<T, U, R>`
105    fn into_box(self) -> BoxStatefulBiTransformer<T, U, R>
106    where
107        Self: Sized + 'static,
108        T: 'static,
109        U: 'static,
110        R: 'static,
111    {
112        let mut trans = self;
113        BoxStatefulBiTransformer::new(move |x, y| trans.apply(x, y))
114    }
115
116    /// Converts to RcStatefulBiTransformer
117    ///
118    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
119    /// after calling this method.
120    ///
121    /// # Default Implementation
122    ///
123    /// The default implementation wraps `self` in an `Rc` and creates an
124    /// `RcStatefulBiTransformer`. Types can override this method to provide more
125    /// efficient conversions.
126    ///
127    /// # Returns
128    ///
129    /// Returns `RcStatefulBiTransformer<T, U, R>`
130    fn into_rc(self) -> RcStatefulBiTransformer<T, U, R>
131    where
132        Self: Sized + 'static,
133        T: 'static,
134        U: 'static,
135        R: 'static,
136    {
137        let mut trans = self;
138        RcStatefulBiTransformer::new(move |x, y| trans.apply(x, y))
139    }
140
141    /// Converts to ArcStatefulBiTransformer
142    ///
143    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
144    /// after calling this method.
145    ///
146    /// # Default Implementation
147    ///
148    /// The default implementation wraps `self` in an `Arc` and creates an
149    /// `ArcStatefulBiTransformer`. Types can override this method to provide more
150    /// efficient conversions.
151    ///
152    /// # Returns
153    ///
154    /// Returns `ArcStatefulBiTransformer<T, U, R>`
155    fn into_arc(self) -> ArcStatefulBiTransformer<T, U, R>
156    where
157        Self: Sized + Send + 'static,
158        T: Send + Sync + 'static,
159        U: Send + Sync + 'static,
160        R: Send + 'static,
161    {
162        let mut trans = self;
163        ArcStatefulBiTransformer::new(move |x, y| trans.apply(x, y))
164    }
165
166    /// Converts bi-transformer to a closure
167    ///
168    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
169    /// after calling this method.
170    ///
171    /// # Default Implementation
172    ///
173    /// The default implementation creates a closure that captures `self`
174    /// and calls its `apply` method. Types can override this method
175    /// to provide more efficient conversions.
176    ///
177    /// # Returns
178    ///
179    /// Returns a closure that implements `FnMut(T, U) -> R`
180    fn into_fn(self) -> impl FnMut(T, U) -> R
181    where
182        Self: Sized + 'static,
183        T: 'static,
184        U: 'static,
185        R: 'static,
186    {
187        let mut trans = self;
188        move |t, u| trans.apply(t, u)
189    }
190
191    /// Converts to BoxBiTransformerOnce
192    ///
193    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
194    /// after calling this method.
195    ///
196    /// # Default Implementation
197    ///
198    /// The default implementation wraps `self` in a `Box` and creates a
199    /// `BoxBiTransformerOnce`. Types can override this method to provide more
200    /// efficient conversions.
201    ///
202    /// # Returns
203    ///
204    /// Returns `BoxBiTransformerOnce<T, U, R>`
205    fn into_once(self) -> BoxBiTransformerOnce<T, U, R>
206    where
207        Self: Sized + 'static,
208        T: 'static,
209        U: 'static,
210        R: 'static,
211    {
212        let mut trans = self;
213        BoxBiTransformerOnce::new(move |t, u| trans.apply(t, u))
214    }
215
216    /// Non-consuming conversion to `BoxStatefulBiTransformer` using `&self`.
217    ///
218    /// Default implementation clones `self` and delegates to `into_box`.
219    fn to_box(&self) -> BoxStatefulBiTransformer<T, U, R>
220    where
221        Self: Sized + Clone + 'static,
222        T: 'static,
223        U: 'static,
224        R: 'static,
225    {
226        self.clone().into_box()
227    }
228
229    /// Non-consuming conversion to `RcStatefulBiTransformer` using `&self`.
230    ///
231    /// Default implementation clones `self` and delegates to `into_rc`.
232    fn to_rc(&self) -> RcStatefulBiTransformer<T, U, R>
233    where
234        Self: Sized + Clone + 'static,
235        T: 'static,
236        U: 'static,
237        R: 'static,
238    {
239        self.clone().into_rc()
240    }
241
242    /// Non-consuming conversion to `ArcStatefulBiTransformer` using `&self`.
243    ///
244    /// Default implementation clones `self` and delegates to `into_arc`.
245    fn to_arc(&self) -> ArcStatefulBiTransformer<T, U, R>
246    where
247        Self: Sized + Clone + Send + Sync + 'static,
248        T: Send + Sync + 'static,
249        U: Send + Sync + 'static,
250        R: Send + Sync + 'static,
251    {
252        self.clone().into_arc()
253    }
254
255    /// Non-consuming conversion to a boxed function using `&self`.
256    ///
257    /// Returns a `Box<dyn FnMut(T, U) -> R>` that clones `self` and calls
258    /// `apply` inside the boxed closure.
259    fn to_fn(&self) -> impl FnMut(T, U) -> R
260    where
261        Self: Sized + Clone + 'static,
262        T: 'static,
263        U: 'static,
264        R: 'static,
265    {
266        self.clone().into_fn()
267    }
268
269    /// Non-consuming conversion to `BoxBiTransformerOnce` using `&self`.
270    ///
271    /// Default implementation clones `self` and delegates to `into_once`.
272    fn to_once(&self) -> BoxBiTransformerOnce<T, U, R>
273    where
274        Self: Sized + Clone + 'static,
275        T: 'static,
276        U: 'static,
277        R: 'static,
278    {
279        self.clone().into_once()
280    }
281}
282
283// ============================================================================
284// BoxStatefulBiTransformer - Box<dyn FnMut(T, U) -> R>
285// ============================================================================
286
287/// BoxStatefulBiTransformer - bi-transformer wrapper based on `Box<dyn Fn>`
288///
289/// A bi-transformer wrapper that provides single ownership with reusable
290/// transformation. The bi-transformer consumes both inputs and can be called
291/// multiple times.
292///
293/// # Features
294///
295/// - **Based on**: `Box<dyn FnMut(T, U) -> R>`
296/// - **Ownership**: Single ownership, cannot be cloned
297/// - **Reusability**: Can be called multiple times (each call consumes its
298///   inputs)
299/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
300///
301/// # Author
302///
303/// Haixing Hu
304pub struct BoxStatefulBiTransformer<T, U, R> {
305    function: Box<dyn FnMut(T, U) -> R>,
306    name: Option<String>,
307}
308
309impl<T, U, R> BoxStatefulBiTransformer<T, U, R>
310where
311    T: 'static,
312    U: 'static,
313    R: 'static,
314{
315    impl_transformer_common_methods!(
316        BoxStatefulBiTransformer<T, U, R>,
317        (FnMut(T, U) -> R + 'static),
318        |f| Box::new(f)
319    );
320
321    impl_box_transformer_methods!(
322        BoxStatefulBiTransformer<T, U, R>,
323        BoxConditionalStatefulBiTransformer,
324        StatefulTransformer
325    );
326}
327
328// Implement constant method for BoxStatefulBiTransformer
329impl_transformer_constant_method!(stateful BoxStatefulBiTransformer<T, U, R>);
330
331// Implement Debug and Display for BoxTransformer
332impl_transformer_debug_display!(BoxStatefulBiTransformer<T, U, R>);
333
334impl<T, U, R> StatefulBiTransformer<T, U, R> for BoxStatefulBiTransformer<T, U, R> {
335    fn apply(&mut self, first: T, second: U) -> R {
336        (self.function)(first, second)
337    }
338
339    fn into_box(self) -> BoxStatefulBiTransformer<T, U, R>
340    where
341        T: 'static,
342        U: 'static,
343        R: 'static,
344    {
345        // Zero-cost: directly return itself
346        self
347    }
348
349    fn into_rc(self) -> RcStatefulBiTransformer<T, U, R>
350    where
351        T: 'static,
352        U: 'static,
353        R: 'static,
354    {
355        RcStatefulBiTransformer::new(self.function)
356    }
357
358    // do NOT override BoxStatefulBiTransformer::into_arc() because BoxStatefulBiTransformer is not Send + Sync
359    // and calling BoxStatefulBiTransformer::into_arc() will cause a compile error
360
361    fn into_fn(self) -> impl FnMut(T, U) -> R
362    where
363        T: 'static,
364        U: 'static,
365        R: 'static,
366    {
367        self.function
368    }
369
370    // do NOT override BoxStatefulBiTransformer::to_xxx() because BoxStatefulBiTransformer is not Clone
371    // and calling BoxStatefulBiTransformer::to_xxx() will cause a compile error
372}
373
374// ============================================================================
375// RcStatefulBiTransformer - Rc<dyn FnMut(T, U) -> R>
376// ============================================================================
377
378/// RcStatefulBiTransformer - single-threaded bi-transformer wrapper
379///
380/// A single-threaded, clonable bi-transformer wrapper optimized for scenarios
381/// that require sharing without thread-safety overhead.
382///
383/// # Features
384///
385/// - **Based on**: `Rc<dyn FnMut(T, U) -> R>`
386/// - **Ownership**: Shared ownership via reference counting (non-atomic)
387/// - **Reusability**: Can be called multiple times (each call consumes its
388///   inputs)
389/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
390/// - **Clonable**: Cheap cloning via `Rc::clone`
391///
392/// # Author
393///
394/// Haixing Hu
395pub struct RcStatefulBiTransformer<T, U, R> {
396    function: Rc<RefCell<dyn FnMut(T, U) -> R>>,
397    name: Option<String>,
398}
399
400impl<T, U, R> RcStatefulBiTransformer<T, U, R>
401where
402    T: 'static,
403    U: 'static,
404    R: 'static,
405{
406    impl_transformer_common_methods!(
407        RcStatefulBiTransformer<T, U, R>,
408        (FnMut(T, U) -> R + 'static),
409        |f| Rc::new(RefCell::new(f))
410    );
411
412    impl_shared_transformer_methods!(
413        RcStatefulBiTransformer<T, U, R>,
414        RcConditionalStatefulBiTransformer,
415        into_rc,
416        StatefulTransformer,
417        'static
418    );
419}
420
421// Implement constant method for RcStatefulBiTransformer
422impl_transformer_constant_method!(stateful RcStatefulBiTransformer<T, U, R>);
423
424// Implement Debug and Display for RcStatefulBiTransformer
425impl_transformer_debug_display!(RcStatefulBiTransformer<T, U, R>);
426
427// Implement Clone for RcStatefulBiTransformer
428impl_transformer_clone!(RcStatefulBiTransformer<T, U, R>);
429
430// Implement StatefulBiTransformer trait for RcStatefulBiTransformer
431impl<T, U, R> StatefulBiTransformer<T, U, R> for RcStatefulBiTransformer<T, U, R> {
432    fn apply(&mut self, first: T, second: U) -> R {
433        let mut self_fn = self.function.borrow_mut();
434        self_fn(first, second)
435    }
436
437    // Generate all conversion methods using the unified macro
438    impl_rc_conversions!(
439        RcStatefulBiTransformer<T, U, R>,
440        BoxStatefulBiTransformer,
441        BoxBiTransformerOnce,
442        FnMut(first: T, second: U) -> R
443    );
444}
445
446// ============================================================================
447// ArcStatefulBiTransformer - Arc<dyn FnMut(T, U) -> R + Send + Sync>
448// ============================================================================
449
450/// ArcStatefulBiTransformer - thread-safe bi-transformer wrapper
451///
452/// A thread-safe, clonable bi-transformer wrapper suitable for multi-threaded
453/// scenarios. Can be called multiple times and shared across threads.
454///
455/// # Features
456///
457/// - **Based on**: `Arc<dyn FnMut(T, U) -> R + Send + Sync>`
458/// - **Ownership**: Shared ownership via reference counting
459/// - **Reusability**: Can be called multiple times (each call consumes its
460///   inputs)
461/// - **Thread Safety**: Thread-safe (`Send + Sync` required)
462/// - **Clonable**: Cheap cloning via `Arc::clone`
463///
464/// # Author
465///
466/// Haixing Hu
467pub struct ArcStatefulBiTransformer<T, U, R> {
468    function: Arc<Mutex<dyn FnMut(T, U) -> R + Send>>,
469    name: Option<String>,
470}
471
472impl<T, U, R> ArcStatefulBiTransformer<T, U, R>
473where
474    T: 'static,
475    U: 'static,
476    R: 'static,
477{
478    impl_transformer_common_methods!(
479        ArcStatefulBiTransformer<T, U, R>,
480        (FnMut(T, U) -> R + Send + 'static),
481        |f| Arc::new(Mutex::new(f))
482    );
483
484    impl_shared_transformer_methods!(
485        ArcStatefulBiTransformer<T, U, R>,
486        ArcConditionalStatefulBiTransformer,
487        into_arc,
488        StatefulTransformer,
489        Send + Sync + 'static
490    );
491}
492
493// Implement constant method for ArcStatefulBiTransformer
494impl_transformer_constant_method!(stateful thread_safe ArcStatefulBiTransformer<T, U, R>);
495
496// Implement Debug and Display for ArcStatefulBiTransformer
497impl_transformer_debug_display!(ArcStatefulBiTransformer<T, U, R>);
498
499// Implement Clone for ArcStatefulBiTransformer
500impl_transformer_clone!(ArcStatefulBiTransformer<T, U, R>);
501
502// Implement StatefulBiTransformer trait for ArcStatefulBiTransformer
503impl<T, U, R> StatefulBiTransformer<T, U, R> for ArcStatefulBiTransformer<T, U, R> {
504    fn apply(&mut self, first: T, second: U) -> R {
505        let mut func = self.function.lock();
506        func(first, second)
507    }
508
509    // Use macro to implement conversion methods
510    impl_arc_conversions!(
511        ArcStatefulBiTransformer<T, U, R>,
512        BoxStatefulBiTransformer,
513        RcStatefulBiTransformer,
514        BoxBiTransformerOnce,
515        FnMut(t: T, u: U) -> R
516    );
517}
518
519// ============================================================================
520// Blanket implementation for standard Fn trait
521// ============================================================================
522
523// Implement StatefulBiTransformer<T, U, R> for any type that implements FnMut(T, U) -> R
524impl_closure_trait!(
525    StatefulBiTransformer<T, U, R>,
526    apply,
527    BoxBiTransformerOnce,
528    FnMut(first: T, second: U) -> R
529);
530
531// ============================================================================
532// FnStatefulBiTransformerOps - Extension trait for FnMut(T, U) -> R bi-transformers
533// ============================================================================
534
535/// Extension trait for closures implementing `FnMut(T, U) -> R`
536///
537/// Provides composition methods (`and_then`, `when`) for bi-transformer
538/// closures and function pointers without requiring explicit wrapping in
539/// `BoxStatefulBiTransformer`.
540///
541/// This trait is automatically implemented for all closures and function
542/// pointers that implement `FnMut(T, U) -> R`.
543///
544/// # Design Rationale
545///
546/// While closures automatically implement `StatefulBiTransformer<T, U, R>` through
547/// blanket implementation, they don't have access to instance methods like
548/// `and_then` and `when`. This extension trait provides those methods,
549/// returning `BoxStatefulBiTransformer` for maximum flexibility.
550///
551/// # Examples
552///
553/// ## Chain composition with and_then
554///
555/// ```rust
556/// use prism3_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
557///
558/// let add = |x: i32, y: i32| x + y;
559/// let double = |x: i32| x * 2;
560///
561/// let composed = add.and_then(double);
562/// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
563/// ```
564///
565/// ## Conditional execution with when
566///
567/// ```rust
568/// use prism3_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
569///
570/// let add = |x: i32, y: i32| x + y;
571/// let multiply = |x: i32, y: i32| x * y;
572///
573/// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0).or_else(multiply);
574///
575/// assert_eq!(conditional.apply(5, 3), 8);   // add
576/// assert_eq!(conditional.apply(-5, 3), -15); // multiply
577/// ```
578///
579/// # Author
580///
581/// Haixing Hu
582pub trait FnStatefulBiTransformerOps<T, U, R>: FnMut(T, U) -> R + Sized + 'static {
583    /// Chain composition - applies self first, then after
584    ///
585    /// Creates a new bi-transformer that applies this bi-transformer first,
586    /// then applies the after transformer to the result. Consumes self and
587    /// returns a `BoxStatefulBiTransformer`.
588    ///
589    /// # Type Parameters
590    ///
591    /// * `S` - The output type of the after transformer
592    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
593    ///
594    /// # Parameters
595    ///
596    /// * `after` - The transformer to apply after self. **Note: This parameter
597    ///   is passed by value and will transfer ownership.** If you need to
598    ///   preserve the original transformer, clone it first (if it implements
599    ///   `Clone`). Can be:
600    ///   - A closure: `|x: R| -> S`
601    ///   - A function pointer: `fn(R) -> S`
602    ///   - A `BoxTransformer<R, S>`
603    ///   - An `RcTransformer<R, S>`
604    ///   - An `ArcTransformer<R, S>`
605    ///   - Any type implementing `Transformer<R, S>`
606    ///
607    /// # Returns
608    ///
609    /// A new `BoxStatefulBiTransformer<T, U, S>` representing the composition
610    ///
611    /// # Examples
612    ///
613    /// ## Direct value passing (ownership transfer)
614    ///
615    /// ```rust
616    /// use prism3_function::{StatefulBiTransformer, FnStatefulBiTransformerOps,
617    ///     BoxTransformer};
618    ///
619    /// let add = |x: i32, y: i32| x + y;
620    /// let to_string = BoxTransformer::new(|x: i32| x.to_string());
621    ///
622    /// // to_string is moved here
623    /// let composed = add.and_then(to_string);
624    /// assert_eq!(composed.apply(20, 22), "42");
625    /// // to_string.apply(10); // Would not compile - moved
626    /// ```
627    ///
628    /// ## Preserving original with clone
629    ///
630    /// ```rust
631    /// use prism3_function::{StatefulBiTransformer, FnStatefulBiTransformerOps,
632    ///     BoxTransformer};
633    ///
634    /// let add = |x: i32, y: i32| x + y;
635    /// let to_string = BoxTransformer::new(|x: i32| x.to_string());
636    ///
637    /// // Clone to preserve original
638    /// let composed = add.and_then(to_string.clone());
639    /// assert_eq!(composed.apply(20, 22), "42");
640    ///
641    /// // Original still usable
642    /// assert_eq!(to_string.apply(10), "10");
643    /// ```
644    fn and_then<S, F>(self, after: F) -> BoxStatefulBiTransformer<T, U, S>
645    where
646        S: 'static,
647        F: StatefulTransformer<R, S> + 'static,
648        T: 'static,
649        U: 'static,
650        R: 'static,
651    {
652        BoxStatefulBiTransformer::new(self).and_then(after)
653    }
654
655    /// Creates a conditional bi-transformer
656    ///
657    /// Returns a bi-transformer that only executes when a bi-predicate is
658    /// satisfied. You must call `or_else()` to provide an alternative
659    /// bi-transformer for when the condition is not satisfied.
660    ///
661    /// # Parameters
662    ///
663    /// * `predicate` - The condition to check. **Note: This parameter is passed
664    ///   by value and will transfer ownership.** If you need to preserve the
665    ///   original bi-predicate, clone it first (if it implements `Clone`).
666    ///   Can be:
667    ///   - A closure: `|x: &T, y: &U| -> bool`
668    ///   - A function pointer: `fn(&T, &U) -> bool`
669    ///   - A `BoxBiPredicate<T, U>`
670    ///   - An `RcBiPredicate<T, U>`
671    ///   - An `ArcBiPredicate<T, U>`
672    ///   - Any type implementing `BiPredicate<T, U>`
673    ///
674    /// # Returns
675    ///
676    /// Returns `BoxConditionalStatefulBiTransformer<T, U, R>`
677    ///
678    /// # Examples
679    ///
680    /// ## Basic usage with or_else
681    ///
682    /// ```rust
683    /// use prism3_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
684    ///
685    /// let add = |x: i32, y: i32| x + y;
686    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0)
687    ///     .or_else(|x: i32, y: i32| x * y);
688    ///
689    /// assert_eq!(conditional.apply(5, 3), 8);
690    /// assert_eq!(conditional.apply(-5, 3), -15);
691    /// ```
692    ///
693    /// ## Preserving bi-predicate with clone
694    ///
695    /// ```rust
696    /// use prism3_function::{StatefulBiTransformer, FnStatefulBiTransformerOps,
697    ///     RcBiPredicate};
698    ///
699    /// let add = |x: i32, y: i32| x + y;
700    /// let both_positive = RcBiPredicate::new(|x: &i32, y: &i32|
701    ///     *x > 0 && *y > 0);
702    ///
703    /// // Clone to preserve original bi-predicate
704    /// let conditional = add.when(both_positive.clone())
705    ///     .or_else(|x: i32, y: i32| x * y);
706    ///
707    /// assert_eq!(conditional.apply(5, 3), 8);
708    ///
709    /// // Original bi-predicate still usable
710    /// assert!(both_positive.test(&5, &3));
711    /// ```
712    fn when<P>(self, predicate: P) -> BoxConditionalStatefulBiTransformer<T, U, R>
713    where
714        P: BiPredicate<T, U> + 'static,
715        T: 'static,
716        U: 'static,
717        R: 'static,
718    {
719        BoxStatefulBiTransformer::new(self).when(predicate)
720    }
721
722    /// Non-consuming conversion to a function using `&self`.
723    ///
724    /// Returns a closure that clones `self` and calls the bi-transformer.
725    /// This method requires that the bi-transformer implements `Clone`.
726    ///
727    /// # Type Parameters
728    ///
729    /// * `F` - The closure type (automatically inferred)
730    ///
731    /// # Returns
732    ///
733    /// Returns a closure that implements `FnMut(T, U) -> R`
734    ///
735    /// # Examples
736    ///
737    /// ```rust
738    /// use prism3_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
739    ///
740    /// let mut counter = 0;
741    /// let transformer = |x: i32, y: i32| {
742    ///     counter += 1;
743    ///     x + y + counter
744    /// };
745    ///
746    /// let mut fn_transformer = transformer.to_fn();
747    /// assert_eq!(fn_transformer(10, 20), 31);
748    /// assert_eq!(fn_transformer(10, 20), 32);
749    /// ```
750    fn to_fn(&self) -> impl FnMut(T, U) -> R
751    where
752        Self: Clone + 'static,
753        T: 'static,
754        U: 'static,
755        R: 'static,
756    {
757        let mut cloned = self.clone();
758        move |t, u| cloned(t, u)
759    }
760}
761
762/// Blanket implementation of FnStatefulBiTransformerOps for all closures
763///
764/// Automatically implements `FnStatefulBiTransformerOps<T, U, R>` for any type that
765/// implements `FnMut(T, U) -> R`.
766///
767/// # Author
768///
769/// Haixing Hu
770impl<T, U, R, F> FnStatefulBiTransformerOps<T, U, R> for F where F: FnMut(T, U) -> R + 'static {}
771
772// ============================================================================
773// BinaryOperator Trait - Marker trait for StatefulBiTransformer<T, T, T>
774// ============================================================================
775
776/// BinaryOperator trait - marker trait for binary operators
777///
778/// A binary operator takes two values of type `T` and produces a value of the
779/// same type `T`. This trait extends `StatefulBiTransformer<T, T, T>` to provide
780/// semantic clarity for same-type binary operations. Equivalent to Java's
781/// `BinaryOperator<T>` which extends `BiFunction<T, T, T>`.
782///
783/// # Automatic Implementation
784///
785/// This trait is automatically implemented for all types that implement
786/// `StatefulBiTransformer<T, T, T>`, so you don't need to implement it manually.
787///
788/// # Type Parameters
789///
790/// * `T` - The type of both input values and the output value
791///
792/// # Examples
793///
794/// ## Using in generic constraints
795///
796/// ```rust
797/// use prism3_function::{BinaryOperator, StatefulBiTransformer};
798///
799/// fn reduce<T, O>(values: Vec<T>, initial: T, op: O) -> T
800/// where
801///     O: BinaryOperator<T>,
802///     T: Clone,
803/// {
804///     values.into_iter().fold(initial, |acc, val| op.apply(acc, val))
805/// }
806///
807/// let sum = |a: i32, b: i32| a + b;
808/// assert_eq!(reduce(vec![1, 2, 3, 4], 0, sum), 10);
809/// ```
810///
811/// ## With concrete types
812///
813/// ```rust
814/// use prism3_function::{BoxBinaryOperator, BinaryOperator, StatefulBiTransformer};
815///
816/// fn create_adder() -> BoxBinaryOperator<i32> {
817///     BoxBinaryOperator::new(|x, y| x + y)
818/// }
819///
820/// let op = create_adder();
821/// assert_eq!(op.apply(20, 22), 42);
822/// ```
823///
824/// # Author
825///
826/// Haixing Hu
827pub trait BinaryOperator<T>: StatefulBiTransformer<T, T, T> {}
828
829/// Blanket implementation of BinaryOperator for all StatefulBiTransformer<T, T, T>
830///
831/// This automatically implements `BinaryOperator<T>` for any type that
832/// implements `StatefulBiTransformer<T, T, T>`.
833///
834/// # Author
835///
836/// Haixing Hu
837impl<F, T> BinaryOperator<T> for F
838where
839    F: StatefulBiTransformer<T, T, T>,
840    T: 'static,
841{
842    // empty
843}
844
845// ============================================================================
846// Type Aliases for BinaryOperator (StatefulBiTransformer<T, T, T>)
847// ============================================================================
848
849/// Type alias for `BoxStatefulBiTransformer<T, T, T>`
850///
851/// Represents a binary operator that takes two values of type `T` and produces
852/// a value of the same type `T`, with single ownership semantics. Equivalent to
853/// Java's `BinaryOperator<T>`.
854///
855/// # Examples
856///
857/// ```rust
858/// use prism3_function::{BoxBinaryOperator, StatefulBiTransformer};
859///
860/// let add: BoxBinaryOperator<i32> = BoxBinaryOperator::new(|x, y| x + y);
861/// assert_eq!(add.apply(20, 22), 42);
862/// ```
863///
864/// # Author
865///
866/// Haixing Hu
867pub type BoxBinaryOperator<T> = BoxStatefulBiTransformer<T, T, T>;
868
869/// Type alias for `ArcStatefulBiTransformer<T, T, T>`
870///
871/// Represents a thread-safe binary operator that takes two values of type `T`
872/// and produces a value of the same type `T`. Equivalent to Java's
873/// `BinaryOperator<T>` with shared, thread-safe ownership.
874///
875/// # Examples
876///
877/// ```rust
878/// use prism3_function::{ArcBinaryOperator, StatefulBiTransformer};
879///
880/// let multiply: ArcBinaryOperator<i32> = ArcBinaryOperator::new(|x, y| x * y);
881/// let multiply_clone = multiply.clone();
882/// assert_eq!(multiply.apply(6, 7), 42);
883/// assert_eq!(multiply_clone.apply(6, 7), 42);
884/// ```
885///
886/// # Author
887///
888/// Haixing Hu
889pub type ArcBinaryOperator<T> = ArcStatefulBiTransformer<T, T, T>;
890
891/// Type alias for `RcStatefulBiTransformer<T, T, T>`
892///
893/// Represents a single-threaded binary operator that takes two values of type
894/// `T` and produces a value of the same type `T`. Equivalent to Java's
895/// `BinaryOperator<T>` with shared, single-threaded ownership.
896///
897/// # Examples
898///
899/// ```rust
900/// use prism3_function::{RcBinaryOperator, StatefulBiTransformer};
901///
902/// let max: RcBinaryOperator<i32> = RcBinaryOperator::new(|x, y| if x > y { x } else { y });
903/// let max_clone = max.clone();
904/// assert_eq!(max.apply(30, 42), 42);
905/// assert_eq!(max_clone.apply(30, 42), 42);
906/// ```
907///
908/// # Author
909///
910/// Haixing Hu
911pub type RcBinaryOperator<T> = RcStatefulBiTransformer<T, T, T>;
912
913// ============================================================================
914// BoxConditionalStatefulBiTransformer - Box-based Conditional StatefulBiTransformer
915// ============================================================================
916
917/// BoxConditionalStatefulBiTransformer struct
918///
919/// A conditional bi-transformer that only executes when a bi-predicate is
920/// satisfied. Uses `BoxStatefulBiTransformer` and `BoxBiPredicate` for single
921/// ownership semantics.
922///
923/// This type is typically created by calling `BoxStatefulBiTransformer::when()` and is
924/// designed to work with the `or_else()` method to create if-then-else logic.
925///
926/// # Features
927///
928/// - **Single Ownership**: Not cloneable, consumes `self` on use
929/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
930/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
931/// - **Implements StatefulBiTransformer**: Can be used anywhere a `StatefulBiTransformer` is expected
932///
933/// # Examples
934///
935/// ## With or_else Branch
936///
937/// ```rust
938/// use prism3_function::{StatefulBiTransformer, BoxStatefulBiTransformer};
939///
940/// let add = BoxStatefulBiTransformer::new(|x: i32, y: i32| x + y);
941/// let multiply = BoxStatefulBiTransformer::new(|x: i32, y: i32| x * y);
942/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
943///
944/// assert_eq!(conditional.apply(5, 3), 8);  // when branch executed
945/// assert_eq!(conditional.apply(-5, 3), -15); // or_else branch executed
946/// ```
947///
948/// # Author
949///
950/// Haixing Hu
951pub struct BoxConditionalStatefulBiTransformer<T, U, R> {
952    transformer: BoxStatefulBiTransformer<T, U, R>,
953    predicate: BoxBiPredicate<T, U>,
954}
955
956// Implement BoxConditionalStatefulBiTransformer
957impl_box_conditional_transformer!(
958    BoxConditionalStatefulBiTransformer<T, U, R>,
959    BoxStatefulBiTransformer,
960    StatefulBiTransformer
961);
962
963// Implement Debug and Display for BoxConditionalStatefulBiTransformer
964impl_conditional_transformer_debug_display!(BoxConditionalStatefulBiTransformer<T, U, R>);
965
966// ============================================================================
967// RcConditionalStatefulBiTransformer - Rc-based Conditional StatefulBiTransformer
968// ============================================================================
969
970/// RcConditionalStatefulBiTransformer struct
971///
972/// A single-threaded conditional bi-transformer that only executes when a
973/// bi-predicate is satisfied. Uses `RcStatefulBiTransformer` and `RcBiPredicate` for
974/// shared ownership within a single thread.
975///
976/// This type is typically created by calling `RcStatefulBiTransformer::when()` and is
977/// designed to work with the `or_else()` method to create if-then-else logic.
978///
979/// # Features
980///
981/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
982/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
983/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
984/// - **No Lock Overhead**: More efficient than `ArcConditionalStatefulBiTransformer`
985///
986/// # Examples
987///
988/// ```rust
989/// use prism3_function::{StatefulBiTransformer, RcStatefulBiTransformer};
990///
991/// let add = RcStatefulBiTransformer::new(|x: i32, y: i32| x + y);
992/// let multiply = RcStatefulBiTransformer::new(|x: i32, y: i32| x * y);
993/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
994///
995/// let conditional_clone = conditional.clone();
996///
997/// assert_eq!(conditional.apply(5, 3), 8);
998/// assert_eq!(conditional_clone.apply(-5, 3), -15);
999/// ```
1000///
1001/// # Author
1002///
1003/// Haixing Hu
1004pub struct RcConditionalStatefulBiTransformer<T, U, R> {
1005    transformer: RcStatefulBiTransformer<T, U, R>,
1006    predicate: RcBiPredicate<T, U>,
1007}
1008
1009// Implement RcConditionalStatefulBiTransformer
1010impl_shared_conditional_transformer!(
1011    RcConditionalStatefulBiTransformer<T, U, R>,
1012    RcStatefulBiTransformer,
1013    StatefulBiTransformer,
1014    into_rc,
1015    'static
1016);
1017
1018// Use macro to generate Debug and Display implementations
1019impl_conditional_transformer_debug_display!(RcConditionalStatefulBiTransformer<T, U, R>);
1020
1021// Implement Clone for RcConditionalStatefulBiTransformer
1022impl_conditional_transformer_clone!(RcConditionalStatefulBiTransformer<T, U, R>);
1023
1024// ============================================================================
1025// ArcConditionalStatefulBiTransformer - Arc-based Conditional StatefulBiTransformer
1026// ============================================================================
1027
1028/// ArcConditionalStatefulBiTransformer struct
1029///
1030/// A thread-safe conditional bi-transformer that only executes when a
1031/// bi-predicate is satisfied. Uses `ArcStatefulBiTransformer` and `ArcBiPredicate` for
1032/// shared ownership across threads.
1033///
1034/// This type is typically created by calling `ArcStatefulBiTransformer::when()` and is
1035/// designed to work with the `or_else()` method to create if-then-else logic.
1036///
1037/// # Features
1038///
1039/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
1040/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
1041/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
1042/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
1043///
1044/// # Examples
1045///
1046/// ```rust
1047/// use prism3_function::{StatefulBiTransformer, ArcStatefulBiTransformer};
1048///
1049/// let add = ArcStatefulBiTransformer::new(|x: i32, y: i32| x + y);
1050/// let multiply = ArcStatefulBiTransformer::new(|x: i32, y: i32| x * y);
1051/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
1052///
1053/// let conditional_clone = conditional.clone();
1054///
1055/// assert_eq!(conditional.apply(5, 3), 8);
1056/// assert_eq!(conditional_clone.apply(-5, 3), -15);
1057/// ```
1058///
1059/// # Author
1060///
1061/// Haixing Hu
1062pub struct ArcConditionalStatefulBiTransformer<T, U, R> {
1063    transformer: ArcStatefulBiTransformer<T, U, R>,
1064    predicate: ArcBiPredicate<T, U>,
1065}
1066
1067impl_shared_conditional_transformer!(
1068    ArcConditionalStatefulBiTransformer<T, U, R>,
1069    ArcStatefulBiTransformer,
1070    StatefulBiTransformer,
1071    into_arc,
1072    Send + Sync + 'static
1073);
1074
1075// Implement Debug and Display for ArcConditionalStatefulBiTransformer
1076impl_conditional_transformer_debug_display!(ArcConditionalStatefulBiTransformer<T, U, R>);
1077
1078// Implement Clone for ArcConditionalStatefulBiTransformer
1079impl_conditional_transformer_clone!(ArcConditionalStatefulBiTransformer<T, U, R>);