prism3_function/
bi_transformer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # BiTransformer Types
10//!
11//! Provides Rust implementations of bi-transformer traits for type conversion
12//! and value transformation with two inputs. BiTransformers consume two input
13//! values (taking ownership) and produce an output value.
14//!
15//! This module provides the `BiTransformer<T, U, R>` trait and three
16//! implementations:
17//!
18//! - [`BoxBiTransformer`]: Single ownership, not cloneable
19//! - [`ArcBiTransformer`]: Thread-safe shared ownership, cloneable
20//! - [`RcBiTransformer`]: Single-threaded shared ownership, cloneable
21//!
22//! # Author
23//!
24//! Hu Haixing
25
26use std::rc::Rc;
27use std::sync::Arc;
28
29use crate::bi_predicate::{ArcBiPredicate, BiPredicate, BoxBiPredicate, RcBiPredicate};
30
31// ============================================================================
32// Core Trait
33// ============================================================================
34
35/// BiTransformer trait - transforms two values to produce a result
36///
37/// Defines the behavior of a bi-transformation: converting two values of types
38/// `T` and `U` to a value of type `R` by consuming the inputs. This is
39/// analogous to `Fn(T, U) -> R` in Rust's standard library.
40///
41/// # Type Parameters
42///
43/// * `T` - The type of the first input value (consumed)
44/// * `U` - The type of the second input value (consumed)
45/// * `R` - The type of the output value
46///
47/// # Author
48///
49/// Hu Haixing
50pub trait BiTransformer<T, U, R> {
51    /// Transforms two input values to produce an output value
52    ///
53    /// # Parameters
54    ///
55    /// * `first` - The first input value to transform (consumed)
56    /// * `second` - The second input value to transform (consumed)
57    ///
58    /// # Returns
59    ///
60    /// The transformed output value
61    fn apply(&self, first: T, second: U) -> R;
62
63    /// Converts to BoxBiTransformer
64    ///
65    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
66    /// after calling this method.
67    ///
68    /// # Default Implementation
69    ///
70    /// The default implementation wraps `self` in a `Box` and creates a
71    /// `BoxBiTransformer`. Types can override this method to provide more
72    /// efficient conversions.
73    ///
74    /// # Returns
75    ///
76    /// Returns `BoxBiTransformer<T, U, R>`
77    fn into_box(self) -> BoxBiTransformer<T, U, R>
78    where
79        Self: Sized + 'static,
80        T: 'static,
81        U: 'static,
82        R: 'static,
83    {
84        BoxBiTransformer::new(move |x, y| self.apply(x, y))
85    }
86
87    /// Converts to RcBiTransformer
88    ///
89    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
90    /// after calling this method.
91    ///
92    /// # Default Implementation
93    ///
94    /// The default implementation wraps `self` in an `Rc` and creates an
95    /// `RcBiTransformer`. Types can override this method to provide more
96    /// efficient conversions.
97    ///
98    /// # Returns
99    ///
100    /// Returns `RcBiTransformer<T, U, R>`
101    fn into_rc(self) -> RcBiTransformer<T, U, R>
102    where
103        Self: Sized + 'static,
104        T: 'static,
105        U: 'static,
106        R: 'static,
107    {
108        RcBiTransformer::new(move |x, y| self.apply(x, y))
109    }
110
111    /// Converts to ArcBiTransformer
112    ///
113    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
114    /// after calling this method.
115    ///
116    /// # Default Implementation
117    ///
118    /// The default implementation wraps `self` in an `Arc` and creates an
119    /// `ArcBiTransformer`. Types can override this method to provide more
120    /// efficient conversions.
121    ///
122    /// # Returns
123    ///
124    /// Returns `ArcBiTransformer<T, U, R>`
125    fn into_arc(self) -> ArcBiTransformer<T, U, R>
126    where
127        Self: Sized + Send + Sync + 'static,
128        T: Send + Sync + 'static,
129        U: Send + Sync + 'static,
130        R: Send + Sync + 'static,
131    {
132        ArcBiTransformer::new(move |x, y| self.apply(x, y))
133    }
134
135    /// Converts bi-transformer to a closure
136    ///
137    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
138    /// after calling this method.
139    ///
140    /// # Default Implementation
141    ///
142    /// The default implementation creates a closure that captures `self`
143    /// and calls its `apply` method. Types can override this method
144    /// to provide more efficient conversions.
145    ///
146    /// # Returns
147    ///
148    /// Returns a closure that implements `Fn(T, U) -> R`
149    fn into_fn(self) -> impl Fn(T, U) -> R
150    where
151        Self: Sized + 'static,
152        T: 'static,
153        U: 'static,
154        R: 'static,
155    {
156        move |t, u| self.apply(t, u)
157    }
158
159    /// Non-consuming conversion to `BoxBiTransformer` using `&self`.
160    ///
161    /// Default implementation clones `self` and delegates to `into_box`.
162    fn to_box(&self) -> BoxBiTransformer<T, U, R>
163    where
164        Self: Sized + Clone + 'static,
165        T: 'static,
166        U: 'static,
167        R: 'static,
168    {
169        self.clone().into_box()
170    }
171
172    /// Non-consuming conversion to `RcBiTransformer` using `&self`.
173    ///
174    /// Default implementation clones `self` and delegates to `into_rc`.
175    fn to_rc(&self) -> RcBiTransformer<T, U, R>
176    where
177        Self: Sized + Clone + 'static,
178        T: 'static,
179        U: 'static,
180        R: 'static,
181    {
182        self.clone().into_rc()
183    }
184
185    /// Non-consuming conversion to `ArcBiTransformer` using `&self`.
186    ///
187    /// Default implementation clones `self` and delegates to `into_arc`.
188    fn to_arc(&self) -> ArcBiTransformer<T, U, R>
189    where
190        Self: Sized + Clone + Send + Sync + 'static,
191        T: Send + Sync + 'static,
192        U: Send + Sync + 'static,
193        R: Send + Sync + 'static,
194    {
195        self.clone().into_arc()
196    }
197
198    /// Non-consuming conversion to a boxed function using `&self`.
199    ///
200    /// Returns a `Box<dyn Fn(T, U) -> R>` that clones `self` and calls
201    /// `apply` inside the boxed closure.
202    fn to_fn(&self) -> impl Fn(T, U) -> R
203    where
204        Self: Sized + Clone + 'static,
205        T: 'static,
206        U: 'static,
207        R: 'static,
208    {
209        self.clone().into_fn()
210    }
211}
212
213// ============================================================================
214// BoxBiTransformer - Box<dyn Fn(T, U) -> R>
215// ============================================================================
216
217/// BoxBiTransformer - bi-transformer wrapper based on `Box<dyn Fn>`
218///
219/// A bi-transformer wrapper that provides single ownership with reusable
220/// transformation. The bi-transformer consumes both inputs and can be called
221/// multiple times.
222///
223/// # Features
224///
225/// - **Based on**: `Box<dyn Fn(T, U) -> R>`
226/// - **Ownership**: Single ownership, cannot be cloned
227/// - **Reusability**: Can be called multiple times (each call consumes its
228///   inputs)
229/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
230///
231/// # Author
232///
233/// Hu Haixing
234pub struct BoxBiTransformer<T, U, R> {
235    function: Box<dyn Fn(T, U) -> R>,
236}
237
238impl<T, U, R> BoxBiTransformer<T, U, R>
239where
240    T: 'static,
241    U: 'static,
242    R: 'static,
243{
244    /// Creates a new BoxBiTransformer
245    ///
246    /// # Parameters
247    ///
248    /// * `f` - The closure or function to wrap
249    ///
250    /// # Examples
251    ///
252    /// ```rust
253    /// use prism3_function::{BoxBiTransformer, BiTransformer};
254    ///
255    /// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
256    /// assert_eq!(add.apply(20, 22), 42);
257    /// ```
258    pub fn new<F>(f: F) -> Self
259    where
260        F: Fn(T, U) -> R + 'static,
261    {
262        BoxBiTransformer {
263            function: Box::new(f),
264        }
265    }
266
267    /// Chain composition - applies self first, then after
268    ///
269    /// Creates a new bi-transformer that applies this bi-transformer first,
270    /// then applies the after transformer to the result. Consumes self.
271    ///
272    /// # Type Parameters
273    ///
274    /// * `S` - The output type of the after transformer
275    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
276    ///
277    /// # Parameters
278    ///
279    /// * `after` - The transformer to apply after self. **Note: This parameter
280    ///   is passed by value and will transfer ownership.** If you need to
281    ///   preserve the original transformer, clone it first (if it implements
282    ///   `Clone`). Can be:
283    ///   - A closure: `|x: R| -> S`
284    ///   - A function pointer: `fn(R) -> S`
285    ///   - A `BoxTransformer<R, S>`
286    ///   - An `RcTransformer<R, S>`
287    ///   - An `ArcTransformer<R, S>`
288    ///   - Any type implementing `Transformer<R, S>`
289    ///
290    /// # Returns
291    ///
292    /// A new `BoxBiTransformer<T, U, S>` representing the composition
293    ///
294    /// # Examples
295    ///
296    /// ## Direct value passing (ownership transfer)
297    ///
298    /// ```rust
299    /// use prism3_function::{BiTransformer, BoxBiTransformer, BoxTransformer};
300    ///
301    /// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
302    /// let double = BoxTransformer::new(|x: i32| x * 2);
303    ///
304    /// // double is moved here
305    /// let composed = add.and_then(double);
306    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
307    /// // double.apply(10); // Would not compile - moved
308    /// ```
309    ///
310    /// ## Preserving original with clone
311    ///
312    /// ```rust
313    /// use prism3_function::{BiTransformer, BoxBiTransformer, BoxTransformer};
314    ///
315    /// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
316    /// let double = BoxTransformer::new(|x: i32| x * 2);
317    ///
318    /// // Clone to preserve original
319    /// let composed = add.and_then(double.clone());
320    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
321    ///
322    /// // Original still usable
323    /// assert_eq!(double.apply(10), 20);
324    /// ```
325    pub fn and_then<S, F>(self, after: F) -> BoxBiTransformer<T, U, S>
326    where
327        S: 'static,
328        F: crate::transformer::Transformer<R, S> + 'static,
329    {
330        let self_fn = self.function;
331        BoxBiTransformer::new(move |t: T, u: U| after.apply(self_fn(t, u)))
332    }
333
334    /// Creates a conditional bi-transformer
335    ///
336    /// Returns a bi-transformer that only executes when a bi-predicate is
337    /// satisfied. You must call `or_else()` to provide an alternative
338    /// bi-transformer for when the condition is not satisfied.
339    ///
340    /// # Parameters
341    ///
342    /// * `predicate` - The condition to check. **Note: This parameter is passed
343    ///   by value and will transfer ownership.** If you need to preserve the
344    ///   original bi-predicate, clone it first (if it implements `Clone`).
345    ///   Can be:
346    ///   - A closure: `|x: &T, y: &U| -> bool`
347    ///   - A function pointer: `fn(&T, &U) -> bool`
348    ///   - A `BoxBiPredicate<T, U>`
349    ///   - An `RcBiPredicate<T, U>`
350    ///   - An `ArcBiPredicate<T, U>`
351    ///   - Any type implementing `BiPredicate<T, U>`
352    ///
353    /// # Returns
354    ///
355    /// Returns `BoxConditionalBiTransformer<T, U, R>`
356    ///
357    /// # Examples
358    ///
359    /// ## Basic usage with or_else
360    ///
361    /// ```rust
362    /// use prism3_function::{BiTransformer, BoxBiTransformer};
363    ///
364    /// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
365    /// let multiply = BoxBiTransformer::new(|x: i32, y: i32| x * y);
366    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
367    ///     .or_else(multiply);
368    ///
369    /// assert_eq!(conditional.apply(5, 3), 8);  // add
370    /// assert_eq!(conditional.apply(-5, 3), -15); // multiply
371    /// ```
372    ///
373    /// ## Preserving bi-predicate with clone
374    ///
375    /// ```rust
376    /// use prism3_function::{BiTransformer, BoxBiTransformer, RcBiPredicate};
377    ///
378    /// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
379    /// let both_positive = RcBiPredicate::new(|x: &i32, y: &i32|
380    ///     *x > 0 && *y > 0);
381    ///
382    /// // Clone to preserve original bi-predicate
383    /// let conditional = add.when(both_positive.clone())
384    ///     .or_else(BoxBiTransformer::new(|x, y| x * y));
385    ///
386    /// assert_eq!(conditional.apply(5, 3), 8);
387    ///
388    /// // Original bi-predicate still usable
389    /// assert!(both_positive.test(&5, &3));
390    /// ```
391    pub fn when<P>(self, predicate: P) -> BoxConditionalBiTransformer<T, U, R>
392    where
393        P: BiPredicate<T, U> + 'static,
394    {
395        BoxConditionalBiTransformer {
396            transformer: self,
397            predicate: predicate.into_box(),
398        }
399    }
400}
401
402impl<T, U, R> BoxBiTransformer<T, U, R>
403where
404    T: 'static,
405    U: 'static,
406    R: Clone + 'static,
407{
408    /// Creates a constant bi-transformer
409    ///
410    /// # Examples
411    ///
412    /// ```rust
413    /// use prism3_function::{BoxBiTransformer, BiTransformer};
414    ///
415    /// let constant = BoxBiTransformer::constant("hello");
416    /// assert_eq!(constant.apply(123, 456), "hello");
417    /// ```
418    pub fn constant(value: R) -> BoxBiTransformer<T, U, R> {
419        BoxBiTransformer::new(move |_, _| value.clone())
420    }
421}
422
423impl<T, U, R> BiTransformer<T, U, R> for BoxBiTransformer<T, U, R> {
424    fn apply(&self, first: T, second: U) -> R {
425        (self.function)(first, second)
426    }
427
428    fn into_box(self) -> BoxBiTransformer<T, U, R>
429    where
430        T: 'static,
431        U: 'static,
432        R: 'static,
433    {
434        // Zero-cost: directly return itself
435        self
436    }
437
438    fn into_rc(self) -> RcBiTransformer<T, U, R>
439    where
440        T: 'static,
441        U: 'static,
442        R: 'static,
443    {
444        RcBiTransformer::new(move |t, u| (self.function)(t, u))
445    }
446
447    // do NOT override BoxBiTransformer::into_arc() because BoxBiTransformer is not Send + Sync
448    // and calling BoxBiTransformer::into_arc() will cause a compile error
449
450    fn into_fn(self) -> impl Fn(T, U) -> R
451    where
452        T: 'static,
453        U: 'static,
454        R: 'static,
455    {
456        move |t: T, u: U| (self.function)(t, u)
457    }
458
459    // do NOT override BoxBiTransformer::to_xxx() because BoxBiTransformer is not Clone
460    // and calling BoxBiTransformer::to_xxx() will cause a compile error
461}
462
463// ============================================================================
464// BoxBiTransformer BiTransformerOnce Implementation
465// ============================================================================
466
467impl<T, U, R> crate::bi_transformer_once::BiTransformerOnce<T, U, R> for BoxBiTransformer<T, U, R>
468where
469    T: 'static,
470    U: 'static,
471    R: 'static,
472{
473    /// Transforms two input values, consuming self and both inputs
474    ///
475    /// # Parameters
476    ///
477    /// * `first` - The first input value (consumed)
478    /// * `second` - The second input value (consumed)
479    ///
480    /// # Returns
481    ///
482    /// The transformed output value
483    fn apply_once(self, first: T, second: U) -> R {
484        (self.function)(first, second)
485    }
486
487    fn into_box_once(self) -> crate::bi_transformer_once::BoxBiTransformerOnce<T, U, R>
488    where
489        T: 'static,
490        U: 'static,
491        R: 'static,
492    {
493        // Zero-cost: directly return itself
494        crate::bi_transformer_once::BoxBiTransformerOnce::new(move |t: T, u: U| {
495            (self.function)(t, u)
496        })
497    }
498
499    fn into_fn_once(self) -> impl FnOnce(T, U) -> R
500    where
501        T: 'static,
502        U: 'static,
503        R: 'static,
504    {
505        move |t: T, u: U| (self.function)(t, u)
506    }
507
508    // do NOT override BoxBiTransformer::to_xxxx() because BoxBiTransformer is not Clone
509    // and calling BoxBiTransformer::to_xxxx() will cause a compile error
510}
511
512// ============================================================================
513// BoxConditionalBiTransformer - Box-based Conditional BiTransformer
514// ============================================================================
515
516/// BoxConditionalBiTransformer struct
517///
518/// A conditional bi-transformer that only executes when a bi-predicate is
519/// satisfied. Uses `BoxBiTransformer` and `BoxBiPredicate` for single
520/// ownership semantics.
521///
522/// This type is typically created by calling `BoxBiTransformer::when()` and is
523/// designed to work with the `or_else()` method to create if-then-else logic.
524///
525/// # Features
526///
527/// - **Single Ownership**: Not cloneable, consumes `self` on use
528/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
529/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
530/// - **Implements BiTransformer**: Can be used anywhere a `BiTransformer` is expected
531///
532/// # Examples
533///
534/// ## With or_else Branch
535///
536/// ```rust
537/// use prism3_function::{BiTransformer, BoxBiTransformer};
538///
539/// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
540/// let multiply = BoxBiTransformer::new(|x: i32, y: i32| x * y);
541/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
542///
543/// assert_eq!(conditional.apply(5, 3), 8);  // when branch executed
544/// assert_eq!(conditional.apply(-5, 3), -15); // or_else branch executed
545/// ```
546///
547/// # Author
548///
549/// Haixing Hu
550pub struct BoxConditionalBiTransformer<T, U, R> {
551    transformer: BoxBiTransformer<T, U, R>,
552    predicate: BoxBiPredicate<T, U>,
553}
554
555impl<T, U, R> BoxConditionalBiTransformer<T, U, R>
556where
557    T: 'static,
558    U: 'static,
559    R: 'static,
560{
561    /// Adds an else branch
562    ///
563    /// Executes the original bi-transformer when the condition is satisfied,
564    /// otherwise executes else_transformer.
565    ///
566    /// # Parameters
567    ///
568    /// * `else_transformer` - The bi-transformer for the else branch, can be:
569    ///   - Closure: `|x: T, y: U| -> R`
570    ///   - `BoxBiTransformer<T, U, R>`, `RcBiTransformer<T, U, R>`, `ArcBiTransformer<T, U, R>`
571    ///   - Any type implementing `BiTransformer<T, U, R>`
572    ///
573    /// # Returns
574    ///
575    /// Returns the composed `BoxBiTransformer<T, U, R>`
576    ///
577    /// # Examples
578    ///
579    /// ## Using a closure (recommended)
580    ///
581    /// ```rust
582    /// use prism3_function::{BiTransformer, BoxBiTransformer};
583    ///
584    /// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
585    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(|x: i32, y: i32| x * y);
586    ///
587    /// assert_eq!(conditional.apply(5, 3), 8);   // Condition satisfied, execute add
588    /// assert_eq!(conditional.apply(-5, 3), -15); // Condition not satisfied, execute multiply
589    /// ```
590    pub fn or_else<F>(self, else_transformer: F) -> BoxBiTransformer<T, U, R>
591    where
592        F: BiTransformer<T, U, R> + 'static,
593    {
594        let pred = self.predicate;
595        let then_trans = self.transformer;
596        BoxBiTransformer::new(move |t, u| {
597            if pred.test(&t, &u) {
598                then_trans.apply(t, u)
599            } else {
600                else_transformer.apply(t, u)
601            }
602        })
603    }
604}
605
606// ============================================================================
607// ArcBiTransformer - Arc<dyn Fn(T, U) -> R + Send + Sync>
608// ============================================================================
609
610/// ArcBiTransformer - thread-safe bi-transformer wrapper
611///
612/// A thread-safe, clonable bi-transformer wrapper suitable for multi-threaded
613/// scenarios. Can be called multiple times and shared across threads.
614///
615/// # Features
616///
617/// - **Based on**: `Arc<dyn Fn(T, U) -> R + Send + Sync>`
618/// - **Ownership**: Shared ownership via reference counting
619/// - **Reusability**: Can be called multiple times (each call consumes its
620///   inputs)
621/// - **Thread Safety**: Thread-safe (`Send + Sync` required)
622/// - **Clonable**: Cheap cloning via `Arc::clone`
623///
624/// # Author
625///
626/// Hu Haixing
627pub struct ArcBiTransformer<T, U, R> {
628    function: Arc<dyn Fn(T, U) -> R + Send + Sync>,
629}
630
631impl<T, U, R> ArcBiTransformer<T, U, R>
632where
633    T: Send + Sync + 'static,
634    U: Send + Sync + 'static,
635    R: 'static,
636{
637    /// Creates a new ArcBiTransformer
638    ///
639    /// # Parameters
640    ///
641    /// * `f` - The closure or function to wrap (must be Send + Sync)
642    ///
643    /// # Examples
644    ///
645    /// ```rust
646    /// use prism3_function::{ArcBiTransformer, BiTransformer};
647    ///
648    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
649    /// assert_eq!(add.apply(20, 22), 42);
650    /// ```
651    pub fn new<F>(f: F) -> Self
652    where
653        F: Fn(T, U) -> R + Send + Sync + 'static,
654    {
655        ArcBiTransformer {
656            function: Arc::new(f),
657        }
658    }
659
660    /// Chain composition - applies self first, then after
661    ///
662    /// Creates a new bi-transformer that applies this bi-transformer first,
663    /// then applies the after transformer to the result. Uses &self, so original
664    /// bi-transformer remains usable.
665    ///
666    /// # Type Parameters
667    ///
668    /// * `S` - The output type of the after transformer
669    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
670    ///
671    /// # Parameters
672    ///
673    /// * `after` - The transformer to apply after self. **Note: This parameter
674    ///   is passed by value and will transfer ownership.** If you need to
675    ///   preserve the original transformer, clone it first (if it implements
676    ///   `Clone`). Must be `Send + Sync`, can be:
677    ///   - A closure: `|x: R| -> S` (must be `Send + Sync`)
678    ///   - A function pointer: `fn(R) -> S`
679    ///   - A `BoxTransformer<R, S>`
680    ///   - An `RcTransformer<R, S>`
681    ///   - An `ArcTransformer<R, S>` (will be moved)
682    ///   - Any type implementing `Transformer<R, S> + Send + Sync`
683    ///
684    /// # Returns
685    ///
686    /// A new `ArcBiTransformer<T, U, S>` representing the composition
687    ///
688    /// # Examples
689    ///
690    /// ## Direct value passing (ownership transfer)
691    ///
692    /// ```rust
693    /// use prism3_function::{BiTransformer, ArcBiTransformer, ArcTransformer};
694    ///
695    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
696    /// let double = ArcTransformer::new(|x: i32| x * 2);
697    ///
698    /// // double is moved here
699    /// let composed = add.and_then(double);
700    ///
701    /// // Original add bi-transformer still usable (uses &self)
702    /// assert_eq!(add.apply(20, 22), 42);
703    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
704    /// // double.apply(10); // Would not compile - moved
705    /// ```
706    ///
707    /// ## Preserving original with clone
708    ///
709    /// ```rust
710    /// use prism3_function::{BiTransformer, ArcBiTransformer, ArcTransformer};
711    ///
712    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
713    /// let double = ArcTransformer::new(|x: i32| x * 2);
714    ///
715    /// // Clone to preserve original
716    /// let composed = add.and_then(double.clone());
717    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
718    ///
719    /// // Both originals still usable
720    /// assert_eq!(add.apply(20, 22), 42);
721    /// assert_eq!(double.apply(10), 20);
722    /// ```
723    pub fn and_then<S, F>(&self, after: F) -> ArcBiTransformer<T, U, S>
724    where
725        S: Send + Sync + 'static,
726        F: crate::transformer::Transformer<R, S> + Send + Sync + 'static,
727    {
728        let self_clone = Arc::clone(&self.function);
729        ArcBiTransformer {
730            function: Arc::new(move |t: T, u: U| after.apply(self_clone(t, u))),
731        }
732    }
733
734    /// Creates a conditional bi-transformer (thread-safe version)
735    ///
736    /// Returns a bi-transformer that only executes when a bi-predicate is
737    /// satisfied. You must call `or_else()` to provide an alternative
738    /// bi-transformer.
739    ///
740    /// # Parameters
741    ///
742    /// * `predicate` - The condition to check. **Note: This parameter is passed
743    ///   by value and will transfer ownership.** If you need to preserve the
744    ///   original bi-predicate, clone it first (if it implements `Clone`).
745    ///   Must be `Send + Sync`, can be:
746    ///   - A closure: `|x: &T, y: &U| -> bool` (requires `Send + Sync`)
747    ///   - A function pointer: `fn(&T, &U) -> bool`
748    ///   - An `ArcBiPredicate<T, U>`
749    ///   - Any type implementing `BiPredicate<T, U> + Send + Sync`
750    ///
751    /// # Returns
752    ///
753    /// Returns `ArcConditionalBiTransformer<T, U, R>`
754    ///
755    /// # Examples
756    ///
757    /// ## Basic usage with or_else
758    ///
759    /// ```rust
760    /// use prism3_function::{BiTransformer, ArcBiTransformer};
761    ///
762    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
763    /// let multiply = ArcBiTransformer::new(|x: i32, y: i32| x * y);
764    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
765    ///     .or_else(multiply);
766    ///
767    /// let conditional_clone = conditional.clone();
768    ///
769    /// assert_eq!(conditional.apply(5, 3), 8);
770    /// assert_eq!(conditional_clone.apply(-5, 3), -15);
771    /// ```
772    ///
773    /// ## Preserving bi-predicate with clone
774    ///
775    /// ```rust
776    /// use prism3_function::{BiTransformer, ArcBiTransformer, ArcBiPredicate};
777    ///
778    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
779    /// let both_positive = ArcBiPredicate::new(|x: &i32, y: &i32|
780    ///     *x > 0 && *y > 0);
781    ///
782    /// // Clone to preserve original bi-predicate
783    /// let conditional = add.when(both_positive.clone())
784    ///     .or_else(ArcBiTransformer::new(|x, y| x * y));
785    ///
786    /// assert_eq!(conditional.apply(5, 3), 8);
787    ///
788    /// // Original bi-predicate still usable
789    /// assert!(both_positive.test(&5, &3));
790    /// ```
791    pub fn when<P>(&self, predicate: P) -> ArcConditionalBiTransformer<T, U, R>
792    where
793        P: BiPredicate<T, U> + Send + Sync + 'static,
794    {
795        ArcConditionalBiTransformer {
796            transformer: self.clone(),
797            predicate: predicate.into_arc(),
798        }
799    }
800}
801
802impl<T, U, R> ArcBiTransformer<T, U, R>
803where
804    T: Send + Sync + 'static,
805    U: Send + Sync + 'static,
806    R: Clone + 'static,
807{
808    /// Creates a constant bi-transformer
809    ///
810    /// # Examples
811    ///
812    /// ```rust
813    /// use prism3_function::{ArcBiTransformer, BiTransformer};
814    ///
815    /// let constant = ArcBiTransformer::constant("hello");
816    /// assert_eq!(constant.apply(123, 456), "hello");
817    /// ```
818    pub fn constant(value: R) -> ArcBiTransformer<T, U, R>
819    where
820        R: Send + Sync,
821    {
822        ArcBiTransformer::new(move |_, _| value.clone())
823    }
824}
825
826impl<T, U, R> BiTransformer<T, U, R> for ArcBiTransformer<T, U, R> {
827    fn apply(&self, first: T, second: U) -> R {
828        (self.function)(first, second)
829    }
830
831    fn into_box(self) -> BoxBiTransformer<T, U, R>
832    where
833        T: 'static,
834        U: 'static,
835        R: 'static,
836    {
837        BoxBiTransformer::new(move |t, u| (self.function)(t, u))
838    }
839
840    fn into_rc(self) -> RcBiTransformer<T, U, R>
841    where
842        T: 'static,
843        U: 'static,
844        R: 'static,
845    {
846        RcBiTransformer::new(move |t, u| (self.function)(t, u))
847    }
848
849    fn into_arc(self) -> ArcBiTransformer<T, U, R>
850    where
851        T: Send + Sync + 'static,
852        U: Send + Sync + 'static,
853        R: Send + Sync + 'static,
854    {
855        // Zero-cost: directly return itself
856        self
857    }
858
859    fn into_fn(self) -> impl Fn(T, U) -> R
860    where
861        T: 'static,
862        U: 'static,
863        R: 'static,
864    {
865        move |t: T, u: U| (self.function)(t, u)
866    }
867
868    fn to_box(&self) -> BoxBiTransformer<T, U, R>
869    where
870        T: 'static,
871        U: 'static,
872        R: 'static,
873    {
874        let self_fn = self.function.clone();
875        BoxBiTransformer::new(move |t, u| self_fn(t, u))
876    }
877
878    fn to_rc(&self) -> RcBiTransformer<T, U, R>
879    where
880        T: 'static,
881        U: 'static,
882        R: 'static,
883    {
884        let self_fn = self.function.clone();
885        RcBiTransformer::new(move |t, u| self_fn(t, u))
886    }
887
888    fn to_arc(&self) -> ArcBiTransformer<T, U, R>
889    where
890        T: Send + Sync + 'static,
891        U: Send + Sync + 'static,
892        R: Send + Sync + 'static,
893    {
894        self.clone()
895    }
896
897    fn to_fn(&self) -> impl Fn(T, U) -> R
898    where
899        T: 'static,
900        U: 'static,
901        R: 'static,
902    {
903        let self_fn = self.function.clone();
904        move |t: T, u: U| self_fn(t, u)
905    }
906}
907
908impl<T, U, R> Clone for ArcBiTransformer<T, U, R> {
909    fn clone(&self) -> Self {
910        ArcBiTransformer {
911            function: Arc::clone(&self.function),
912        }
913    }
914}
915
916// ============================================================================
917// ArcBiTransformer BiTransformerOnce Implementation
918// ============================================================================
919
920impl<T, U, R> crate::bi_transformer_once::BiTransformerOnce<T, U, R> for ArcBiTransformer<T, U, R>
921where
922    T: 'static,
923    U: 'static,
924    R: 'static,
925{
926    /// Transforms two input values, consuming self and both inputs
927    ///
928    /// # Parameters
929    ///
930    /// * `first` - The first input value (consumed)
931    /// * `second` - The second input value (consumed)
932    ///
933    /// # Returns
934    ///
935    /// The transformed output value
936    fn apply_once(self, first: T, second: U) -> R {
937        (self.function)(first, second)
938    }
939
940    fn into_box_once(self) -> crate::bi_transformer_once::BoxBiTransformerOnce<T, U, R>
941    where
942        T: 'static,
943        U: 'static,
944        R: 'static,
945    {
946        crate::bi_transformer_once::BoxBiTransformerOnce::new(move |t: T, u: U| {
947            (self.function)(t, u)
948        })
949    }
950
951    fn into_fn_once(self) -> impl FnOnce(T, U) -> R
952    where
953        T: 'static,
954        U: 'static,
955        R: 'static,
956    {
957        move |t: T, u: U| (self.function)(t, u)
958    }
959
960    fn to_box_once(&self) -> crate::bi_transformer_once::BoxBiTransformerOnce<T, U, R>
961    where
962        T: 'static,
963        U: 'static,
964        R: 'static,
965    {
966        let self_fn = self.function.clone();
967        crate::bi_transformer_once::BoxBiTransformerOnce::new(move |t: T, u: U| self_fn(t, u))
968    }
969
970    fn to_fn_once(&self) -> impl FnOnce(T, U) -> R
971    where
972        T: 'static,
973        U: 'static,
974        R: 'static,
975    {
976        let self_fn = self.function.clone();
977        move |t: T, u: U| self_fn(t, u)
978    }
979}
980
981// ============================================================================
982// ArcConditionalBiTransformer - Arc-based Conditional BiTransformer
983// ============================================================================
984
985/// ArcConditionalBiTransformer struct
986///
987/// A thread-safe conditional bi-transformer that only executes when a
988/// bi-predicate is satisfied. Uses `ArcBiTransformer` and `ArcBiPredicate` for
989/// shared ownership across threads.
990///
991/// This type is typically created by calling `ArcBiTransformer::when()` and is
992/// designed to work with the `or_else()` method to create if-then-else logic.
993///
994/// # Features
995///
996/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
997/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
998/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
999/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
1000///
1001/// # Examples
1002///
1003/// ```rust
1004/// use prism3_function::{BiTransformer, ArcBiTransformer};
1005///
1006/// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
1007/// let multiply = ArcBiTransformer::new(|x: i32, y: i32| x * y);
1008/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
1009///
1010/// let conditional_clone = conditional.clone();
1011///
1012/// assert_eq!(conditional.apply(5, 3), 8);
1013/// assert_eq!(conditional_clone.apply(-5, 3), -15);
1014/// ```
1015///
1016/// # Author
1017///
1018/// Haixing Hu
1019pub struct ArcConditionalBiTransformer<T, U, R> {
1020    transformer: ArcBiTransformer<T, U, R>,
1021    predicate: ArcBiPredicate<T, U>,
1022}
1023
1024impl<T, U, R> ArcConditionalBiTransformer<T, U, R>
1025where
1026    T: Send + Sync + 'static,
1027    U: Send + Sync + 'static,
1028    R: 'static,
1029{
1030    /// Adds an else branch (thread-safe version)
1031    ///
1032    /// Executes the original bi-transformer when the condition is satisfied,
1033    /// otherwise executes else_transformer.
1034    ///
1035    /// # Parameters
1036    ///
1037    /// * `else_transformer` - The bi-transformer for the else branch, can be:
1038    ///   - Closure: `|x: T, y: U| -> R` (must be `Send + Sync`)
1039    ///   - `ArcBiTransformer<T, U, R>`, `BoxBiTransformer<T, U, R>`
1040    ///   - Any type implementing `BiTransformer<T, U, R> + Send + Sync`
1041    ///
1042    /// # Returns
1043    ///
1044    /// Returns the composed `ArcBiTransformer<T, U, R>`
1045    ///
1046    /// # Examples
1047    ///
1048    /// ## Using a closure (recommended)
1049    ///
1050    /// ```rust
1051    /// use prism3_function::{BiTransformer, ArcBiTransformer};
1052    ///
1053    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
1054    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(|x: i32, y: i32| x * y);
1055    ///
1056    /// assert_eq!(conditional.apply(5, 3), 8);
1057    /// assert_eq!(conditional.apply(-5, 3), -15);
1058    /// ```
1059    pub fn or_else<F>(&self, else_transformer: F) -> ArcBiTransformer<T, U, R>
1060    where
1061        F: BiTransformer<T, U, R> + Send + Sync + 'static,
1062        R: Send + Sync,
1063    {
1064        let pred = self.predicate.clone();
1065        let then_trans = self.transformer.clone();
1066        ArcBiTransformer::new(move |t, u| {
1067            if pred.test(&t, &u) {
1068                then_trans.apply(t, u)
1069            } else {
1070                else_transformer.apply(t, u)
1071            }
1072        })
1073    }
1074}
1075
1076impl<T, U, R> Clone for ArcConditionalBiTransformer<T, U, R> {
1077    /// Clones the conditional bi-transformer
1078    ///
1079    /// Creates a new instance that shares the underlying bi-transformer and
1080    /// bi-predicate with the original instance.
1081    fn clone(&self) -> Self {
1082        ArcConditionalBiTransformer {
1083            transformer: self.transformer.clone(),
1084            predicate: self.predicate.clone(),
1085        }
1086    }
1087}
1088
1089// ============================================================================
1090// RcBiTransformer - Rc<dyn Fn(T, U) -> R>
1091// ============================================================================
1092
1093/// RcBiTransformer - single-threaded bi-transformer wrapper
1094///
1095/// A single-threaded, clonable bi-transformer wrapper optimized for scenarios
1096/// that require sharing without thread-safety overhead.
1097///
1098/// # Features
1099///
1100/// - **Based on**: `Rc<dyn Fn(T, U) -> R>`
1101/// - **Ownership**: Shared ownership via reference counting (non-atomic)
1102/// - **Reusability**: Can be called multiple times (each call consumes its
1103///   inputs)
1104/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
1105/// - **Clonable**: Cheap cloning via `Rc::clone`
1106///
1107/// # Author
1108///
1109/// Hu Haixing
1110pub struct RcBiTransformer<T, U, R> {
1111    function: Rc<dyn Fn(T, U) -> R>,
1112}
1113
1114impl<T, U, R> RcBiTransformer<T, U, R>
1115where
1116    T: 'static,
1117    U: 'static,
1118    R: 'static,
1119{
1120    /// Creates a new RcBiTransformer
1121    ///
1122    /// # Parameters
1123    ///
1124    /// * `f` - The closure or function to wrap
1125    ///
1126    /// # Examples
1127    ///
1128    /// ```rust
1129    /// use prism3_function::{RcBiTransformer, BiTransformer};
1130    ///
1131    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1132    /// assert_eq!(add.apply(20, 22), 42);
1133    /// ```
1134    pub fn new<F>(f: F) -> Self
1135    where
1136        F: Fn(T, U) -> R + 'static,
1137    {
1138        RcBiTransformer {
1139            function: Rc::new(f),
1140        }
1141    }
1142
1143    /// Chain composition - applies self first, then after
1144    ///
1145    /// Creates a new bi-transformer that applies this bi-transformer first,
1146    /// then applies the after transformer to the result. Uses &self, so original
1147    /// bi-transformer remains usable.
1148    ///
1149    /// # Type Parameters
1150    ///
1151    /// * `S` - The output type of the after transformer
1152    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
1153    ///
1154    /// # Parameters
1155    ///
1156    /// * `after` - The transformer to apply after self. **Note: This parameter
1157    ///   is passed by value and will transfer ownership.** If you need to
1158    ///   preserve the original transformer, clone it first (if it implements
1159    ///   `Clone`). Can be:
1160    ///   - A closure: `|x: R| -> S`
1161    ///   - A function pointer: `fn(R) -> S`
1162    ///   - A `BoxTransformer<R, S>`
1163    ///   - An `RcTransformer<R, S>` (will be moved)
1164    ///   - An `ArcTransformer<R, S>`
1165    ///   - Any type implementing `Transformer<R, S>`
1166    ///
1167    /// # Returns
1168    ///
1169    /// A new `RcBiTransformer<T, U, S>` representing the composition
1170    ///
1171    /// # Examples
1172    ///
1173    /// ## Direct value passing (ownership transfer)
1174    ///
1175    /// ```rust
1176    /// use prism3_function::{BiTransformer, RcBiTransformer, RcTransformer};
1177    ///
1178    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1179    /// let double = RcTransformer::new(|x: i32| x * 2);
1180    ///
1181    /// // double is moved here
1182    /// let composed = add.and_then(double);
1183    ///
1184    /// // Original add bi-transformer still usable (uses &self)
1185    /// assert_eq!(add.apply(20, 22), 42);
1186    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
1187    /// // double.apply(10); // Would not compile - moved
1188    /// ```
1189    ///
1190    /// ## Preserving original with clone
1191    ///
1192    /// ```rust
1193    /// use prism3_function::{BiTransformer, RcBiTransformer, RcTransformer};
1194    ///
1195    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1196    /// let double = RcTransformer::new(|x: i32| x * 2);
1197    ///
1198    /// // Clone to preserve original
1199    /// let composed = add.and_then(double.clone());
1200    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
1201    ///
1202    /// // Both originals still usable
1203    /// assert_eq!(add.apply(20, 22), 42);
1204    /// assert_eq!(double.apply(10), 20);
1205    /// ```
1206    pub fn and_then<S, F>(&self, after: F) -> RcBiTransformer<T, U, S>
1207    where
1208        S: 'static,
1209        F: crate::transformer::Transformer<R, S> + 'static,
1210    {
1211        let self_clone = Rc::clone(&self.function);
1212        RcBiTransformer {
1213            function: Rc::new(move |t: T, u: U| after.apply(self_clone(t, u))),
1214        }
1215    }
1216
1217    /// Creates a conditional bi-transformer (single-threaded shared version)
1218    ///
1219    /// Returns a bi-transformer that only executes when a bi-predicate is
1220    /// satisfied. You must call `or_else()` to provide an alternative
1221    /// bi-transformer.
1222    ///
1223    /// # Parameters
1224    ///
1225    /// * `predicate` - The condition to check. **Note: This parameter is passed
1226    ///   by value and will transfer ownership.** If you need to preserve the
1227    ///   original bi-predicate, clone it first (if it implements `Clone`).
1228    ///   Can be:
1229    ///   - A closure: `|x: &T, y: &U| -> bool`
1230    ///   - A function pointer: `fn(&T, &U) -> bool`
1231    ///   - A `BoxBiPredicate<T, U>`
1232    ///   - An `RcBiPredicate<T, U>`
1233    ///   - An `ArcBiPredicate<T, U>`
1234    ///   - Any type implementing `BiPredicate<T, U>`
1235    ///
1236    /// # Returns
1237    ///
1238    /// Returns `RcConditionalBiTransformer<T, U, R>`
1239    ///
1240    /// # Examples
1241    ///
1242    /// ## Basic usage with or_else
1243    ///
1244    /// ```rust
1245    /// use prism3_function::{BiTransformer, RcBiTransformer};
1246    ///
1247    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1248    /// let multiply = RcBiTransformer::new(|x: i32, y: i32| x * y);
1249    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
1250    ///     .or_else(multiply);
1251    ///
1252    /// let conditional_clone = conditional.clone();
1253    ///
1254    /// assert_eq!(conditional.apply(5, 3), 8);
1255    /// assert_eq!(conditional_clone.apply(-5, 3), -15);
1256    /// ```
1257    ///
1258    /// ## Preserving bi-predicate with clone
1259    ///
1260    /// ```rust
1261    /// use prism3_function::{BiTransformer, RcBiTransformer, RcBiPredicate};
1262    ///
1263    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1264    /// let both_positive = RcBiPredicate::new(|x: &i32, y: &i32|
1265    ///     *x > 0 && *y > 0);
1266    ///
1267    /// // Clone to preserve original bi-predicate
1268    /// let conditional = add.when(both_positive.clone())
1269    ///     .or_else(RcBiTransformer::new(|x, y| x * y));
1270    ///
1271    /// assert_eq!(conditional.apply(5, 3), 8);
1272    ///
1273    /// // Original bi-predicate still usable
1274    /// assert!(both_positive.test(&5, &3));
1275    /// ```
1276    pub fn when<P>(&self, predicate: P) -> RcConditionalBiTransformer<T, U, R>
1277    where
1278        P: BiPredicate<T, U> + 'static,
1279    {
1280        RcConditionalBiTransformer {
1281            transformer: self.clone(),
1282            predicate: predicate.into_rc(),
1283        }
1284    }
1285}
1286
1287impl<T, U, R> RcBiTransformer<T, U, R>
1288where
1289    T: 'static,
1290    U: 'static,
1291    R: Clone + 'static,
1292{
1293    /// Creates a constant bi-transformer
1294    ///
1295    /// # Examples
1296    ///
1297    /// ```rust
1298    /// use prism3_function::{RcBiTransformer, BiTransformer};
1299    ///
1300    /// let constant = RcBiTransformer::constant("hello");
1301    /// assert_eq!(constant.apply(123, 456), "hello");
1302    /// ```
1303    pub fn constant(value: R) -> RcBiTransformer<T, U, R> {
1304        RcBiTransformer::new(move |_, _| value.clone())
1305    }
1306}
1307
1308impl<T, U, R> BiTransformer<T, U, R> for RcBiTransformer<T, U, R> {
1309    fn apply(&self, first: T, second: U) -> R {
1310        (self.function)(first, second)
1311    }
1312
1313    fn into_box(self) -> BoxBiTransformer<T, U, R>
1314    where
1315        T: 'static,
1316        U: 'static,
1317        R: 'static,
1318    {
1319        BoxBiTransformer::new(move |t, u| (self.function)(t, u))
1320    }
1321
1322    fn into_rc(self) -> RcBiTransformer<T, U, R>
1323    where
1324        T: 'static,
1325        U: 'static,
1326        R: 'static,
1327    {
1328        // Zero-cost: directly return itself
1329        self
1330    }
1331
1332    // do NOT override RcBiTransformer::into_arc() because RcBiTransformer is not Send + Sync
1333    // and calling RcBiTransformer::into_arc() will cause a compile error
1334
1335    fn into_fn(self) -> impl Fn(T, U) -> R
1336    where
1337        T: 'static,
1338        U: 'static,
1339        R: 'static,
1340    {
1341        move |t: T, u: U| (self.function)(t, u)
1342    }
1343
1344    fn to_box(&self) -> BoxBiTransformer<T, U, R>
1345    where
1346        T: 'static,
1347        U: 'static,
1348        R: 'static,
1349    {
1350        let self_fn = self.function.clone();
1351        BoxBiTransformer::new(move |t, u| self_fn(t, u))
1352    }
1353
1354    fn to_rc(&self) -> RcBiTransformer<T, U, R>
1355    where
1356        T: 'static,
1357        U: 'static,
1358        R: 'static,
1359    {
1360        self.clone()
1361    }
1362
1363    // do NOT override RcBiTransformer::to_arc() because RcBiTransformer is not Send + Sync
1364    // and calling RcBiTransformer::to_arc() will cause a compile error
1365
1366    fn to_fn(&self) -> impl Fn(T, U) -> R
1367    where
1368        T: 'static,
1369        U: 'static,
1370        R: 'static,
1371    {
1372        let self_fn = self.function.clone();
1373        move |t: T, u: U| self_fn(t, u)
1374    }
1375}
1376
1377impl<T, U, R> Clone for RcBiTransformer<T, U, R> {
1378    fn clone(&self) -> Self {
1379        RcBiTransformer {
1380            function: Rc::clone(&self.function),
1381        }
1382    }
1383}
1384
1385// ============================================================================
1386// RcBiTransformer BiTransformerOnce Implementation
1387// ============================================================================
1388
1389impl<T, U, R> crate::bi_transformer_once::BiTransformerOnce<T, U, R> for RcBiTransformer<T, U, R>
1390where
1391    T: 'static,
1392    U: 'static,
1393    R: 'static,
1394{
1395    /// Transforms two input values, consuming self and both inputs
1396    ///
1397    /// # Parameters
1398    ///
1399    /// * `first` - The first input value (consumed)
1400    /// * `second` - The second input value (consumed)
1401    ///
1402    /// # Returns
1403    ///
1404    /// The transformed output value
1405    fn apply_once(self, first: T, second: U) -> R {
1406        (self.function)(first, second)
1407    }
1408
1409    fn into_box_once(self) -> crate::bi_transformer_once::BoxBiTransformerOnce<T, U, R>
1410    where
1411        T: 'static,
1412        U: 'static,
1413        R: 'static,
1414    {
1415        crate::bi_transformer_once::BoxBiTransformerOnce::new(move |t: T, u: U| {
1416            (self.function)(t, u)
1417        })
1418    }
1419
1420    fn into_fn_once(self) -> impl FnOnce(T, U) -> R
1421    where
1422        T: 'static,
1423        U: 'static,
1424        R: 'static,
1425    {
1426        move |t: T, u: U| (self.function)(t, u)
1427    }
1428
1429    fn to_box_once(&self) -> crate::bi_transformer_once::BoxBiTransformerOnce<T, U, R>
1430    where
1431        T: 'static,
1432        U: 'static,
1433        R: 'static,
1434    {
1435        let self_fn = self.function.clone();
1436        crate::bi_transformer_once::BoxBiTransformerOnce::new(move |t: T, u: U| self_fn(t, u))
1437    }
1438
1439    fn to_fn_once(&self) -> impl FnOnce(T, U) -> R
1440    where
1441        T: 'static,
1442        U: 'static,
1443        R: 'static,
1444    {
1445        let self_fn = self.function.clone();
1446        move |t: T, u: U| self_fn(t, u)
1447    }
1448}
1449
1450// ============================================================================
1451// RcConditionalBiTransformer - Rc-based Conditional BiTransformer
1452// ============================================================================
1453
1454/// RcConditionalBiTransformer struct
1455///
1456/// A single-threaded conditional bi-transformer that only executes when a
1457/// bi-predicate is satisfied. Uses `RcBiTransformer` and `RcBiPredicate` for
1458/// shared ownership within a single thread.
1459///
1460/// This type is typically created by calling `RcBiTransformer::when()` and is
1461/// designed to work with the `or_else()` method to create if-then-else logic.
1462///
1463/// # Features
1464///
1465/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
1466/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
1467/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
1468/// - **No Lock Overhead**: More efficient than `ArcConditionalBiTransformer`
1469///
1470/// # Examples
1471///
1472/// ```rust
1473/// use prism3_function::{BiTransformer, RcBiTransformer};
1474///
1475/// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1476/// let multiply = RcBiTransformer::new(|x: i32, y: i32| x * y);
1477/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
1478///
1479/// let conditional_clone = conditional.clone();
1480///
1481/// assert_eq!(conditional.apply(5, 3), 8);
1482/// assert_eq!(conditional_clone.apply(-5, 3), -15);
1483/// ```
1484///
1485/// # Author
1486///
1487/// Haixing Hu
1488pub struct RcConditionalBiTransformer<T, U, R> {
1489    transformer: RcBiTransformer<T, U, R>,
1490    predicate: RcBiPredicate<T, U>,
1491}
1492
1493impl<T, U, R> RcConditionalBiTransformer<T, U, R>
1494where
1495    T: 'static,
1496    U: 'static,
1497    R: 'static,
1498{
1499    /// Adds an else branch (single-threaded shared version)
1500    ///
1501    /// Executes the original bi-transformer when the condition is satisfied,
1502    /// otherwise executes else_transformer.
1503    ///
1504    /// # Parameters
1505    ///
1506    /// * `else_transformer` - The bi-transformer for the else branch, can be:
1507    ///   - Closure: `|x: T, y: U| -> R`
1508    ///   - `RcBiTransformer<T, U, R>`, `BoxBiTransformer<T, U, R>`
1509    ///   - Any type implementing `BiTransformer<T, U, R>`
1510    ///
1511    /// # Returns
1512    ///
1513    /// Returns the composed `RcBiTransformer<T, U, R>`
1514    ///
1515    /// # Examples
1516    ///
1517    /// ## Using a closure (recommended)
1518    ///
1519    /// ```rust
1520    /// use prism3_function::{BiTransformer, RcBiTransformer};
1521    ///
1522    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1523    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(|x: i32, y: i32| x * y);
1524    ///
1525    /// assert_eq!(conditional.apply(5, 3), 8);
1526    /// assert_eq!(conditional.apply(-5, 3), -15);
1527    /// ```
1528    pub fn or_else<F>(&self, else_transformer: F) -> RcBiTransformer<T, U, R>
1529    where
1530        F: BiTransformer<T, U, R> + 'static,
1531    {
1532        let pred = self.predicate.clone();
1533        let then_trans = self.transformer.clone();
1534        RcBiTransformer::new(move |t, u| {
1535            if pred.test(&t, &u) {
1536                then_trans.apply(t, u)
1537            } else {
1538                else_transformer.apply(t, u)
1539            }
1540        })
1541    }
1542}
1543
1544impl<T, U, R> Clone for RcConditionalBiTransformer<T, U, R> {
1545    /// Clones the conditional bi-transformer
1546    ///
1547    /// Creates a new instance that shares the underlying bi-transformer and
1548    /// bi-predicate with the original instance.
1549    fn clone(&self) -> Self {
1550        RcConditionalBiTransformer {
1551            transformer: self.transformer.clone(),
1552            predicate: self.predicate.clone(),
1553        }
1554    }
1555}
1556
1557// ============================================================================
1558// Blanket implementation for standard Fn trait
1559// ============================================================================
1560
1561/// Implement BiTransformer<T, U, R> for any type that implements Fn(T, U) -> R
1562///
1563/// This allows closures and function pointers to be used directly with our
1564/// BiTransformer trait without wrapping.
1565///
1566/// # Examples
1567///
1568/// ```rust
1569/// use prism3_function::BiTransformer;
1570///
1571/// fn add(x: i32, y: i32) -> i32 { x + y }
1572///
1573/// assert_eq!(add.apply(20, 22), 42);
1574///
1575/// let multiply = |x: i32, y: i32| x * y;
1576/// assert_eq!(multiply.apply(6, 7), 42);
1577/// ```
1578///
1579/// # Author
1580///
1581/// Hu Haixing
1582impl<F, T, U, R> BiTransformer<T, U, R> for F
1583where
1584    F: Fn(T, U) -> R,
1585    T: 'static,
1586    U: 'static,
1587    R: 'static,
1588{
1589    fn apply(&self, first: T, second: U) -> R {
1590        self(first, second)
1591    }
1592
1593    fn into_box(self) -> BoxBiTransformer<T, U, R>
1594    where
1595        Self: Sized + 'static,
1596    {
1597        BoxBiTransformer::new(self)
1598    }
1599
1600    fn into_rc(self) -> RcBiTransformer<T, U, R>
1601    where
1602        Self: Sized + 'static,
1603    {
1604        RcBiTransformer::new(self)
1605    }
1606
1607    fn into_arc(self) -> ArcBiTransformer<T, U, R>
1608    where
1609        Self: Sized + Send + Sync + 'static,
1610        T: Send + Sync + 'static,
1611        U: Send + Sync + 'static,
1612        R: Send + Sync + 'static,
1613    {
1614        ArcBiTransformer::new(self)
1615    }
1616
1617    fn into_fn(self) -> impl Fn(T, U) -> R
1618    where
1619        Self: Sized + 'static,
1620    {
1621        move |t: T, u: U| self(t, u)
1622    }
1623
1624    fn to_box(&self) -> BoxBiTransformer<T, U, R>
1625    where
1626        Self: Sized + Clone + 'static,
1627        T: 'static,
1628        U: 'static,
1629        R: 'static,
1630    {
1631        BoxBiTransformer::new(self.clone())
1632    }
1633
1634    fn to_rc(&self) -> RcBiTransformer<T, U, R>
1635    where
1636        Self: Sized + Clone + 'static,
1637        T: 'static,
1638        U: 'static,
1639        R: 'static,
1640    {
1641        RcBiTransformer::new(self.clone())
1642    }
1643
1644    fn to_arc(&self) -> ArcBiTransformer<T, U, R>
1645    where
1646        Self: Sized + Clone + Send + Sync + 'static,
1647        T: Send + Sync + 'static,
1648        U: Send + Sync + 'static,
1649        R: Send + Sync + 'static,
1650    {
1651        ArcBiTransformer::new(self.clone())
1652    }
1653
1654    fn to_fn(&self) -> impl Fn(T, U) -> R
1655    where
1656        Self: Sized + Clone + 'static,
1657        T: 'static,
1658        U: 'static,
1659        R: 'static,
1660    {
1661        self.clone()
1662    }
1663}
1664
1665// ============================================================================
1666// FnBiTransformerOps - Extension trait for Fn(T, U) -> R bi-transformers
1667// ============================================================================
1668
1669/// Extension trait for closures implementing `Fn(T, U) -> R`
1670///
1671/// Provides composition methods (`and_then`, `when`) for bi-transformer
1672/// closures and function pointers without requiring explicit wrapping in
1673/// `BoxBiTransformer`.
1674///
1675/// This trait is automatically implemented for all closures and function
1676/// pointers that implement `Fn(T, U) -> R`.
1677///
1678/// # Design Rationale
1679///
1680/// While closures automatically implement `BiTransformer<T, U, R>` through
1681/// blanket implementation, they don't have access to instance methods like
1682/// `and_then` and `when`. This extension trait provides those methods,
1683/// returning `BoxBiTransformer` for maximum flexibility.
1684///
1685/// # Examples
1686///
1687/// ## Chain composition with and_then
1688///
1689/// ```rust
1690/// use prism3_function::{BiTransformer, FnBiTransformerOps};
1691///
1692/// let add = |x: i32, y: i32| x + y;
1693/// let double = |x: i32| x * 2;
1694///
1695/// let composed = add.and_then(double);
1696/// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
1697/// ```
1698///
1699/// ## Conditional execution with when
1700///
1701/// ```rust
1702/// use prism3_function::{BiTransformer, FnBiTransformerOps};
1703///
1704/// let add = |x: i32, y: i32| x + y;
1705/// let multiply = |x: i32, y: i32| x * y;
1706///
1707/// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0).or_else(multiply);
1708///
1709/// assert_eq!(conditional.apply(5, 3), 8);   // add
1710/// assert_eq!(conditional.apply(-5, 3), -15); // multiply
1711/// ```
1712///
1713/// # Author
1714///
1715/// Hu Haixing
1716pub trait FnBiTransformerOps<T, U, R>: Fn(T, U) -> R + Sized + 'static {
1717    /// Chain composition - applies self first, then after
1718    ///
1719    /// Creates a new bi-transformer that applies this bi-transformer first,
1720    /// then applies the after transformer to the result. Consumes self and
1721    /// returns a `BoxBiTransformer`.
1722    ///
1723    /// # Type Parameters
1724    ///
1725    /// * `S` - The output type of the after transformer
1726    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
1727    ///
1728    /// # Parameters
1729    ///
1730    /// * `after` - The transformer to apply after self. **Note: This parameter
1731    ///   is passed by value and will transfer ownership.** If you need to
1732    ///   preserve the original transformer, clone it first (if it implements
1733    ///   `Clone`). Can be:
1734    ///   - A closure: `|x: R| -> S`
1735    ///   - A function pointer: `fn(R) -> S`
1736    ///   - A `BoxTransformer<R, S>`
1737    ///   - An `RcTransformer<R, S>`
1738    ///   - An `ArcTransformer<R, S>`
1739    ///   - Any type implementing `Transformer<R, S>`
1740    ///
1741    /// # Returns
1742    ///
1743    /// A new `BoxBiTransformer<T, U, S>` representing the composition
1744    ///
1745    /// # Examples
1746    ///
1747    /// ## Direct value passing (ownership transfer)
1748    ///
1749    /// ```rust
1750    /// use prism3_function::{BiTransformer, FnBiTransformerOps,
1751    ///     BoxTransformer};
1752    ///
1753    /// let add = |x: i32, y: i32| x + y;
1754    /// let to_string = BoxTransformer::new(|x: i32| x.to_string());
1755    ///
1756    /// // to_string is moved here
1757    /// let composed = add.and_then(to_string);
1758    /// assert_eq!(composed.apply(20, 22), "42");
1759    /// // to_string.apply(10); // Would not compile - moved
1760    /// ```
1761    ///
1762    /// ## Preserving original with clone
1763    ///
1764    /// ```rust
1765    /// use prism3_function::{BiTransformer, FnBiTransformerOps,
1766    ///     BoxTransformer};
1767    ///
1768    /// let add = |x: i32, y: i32| x + y;
1769    /// let to_string = BoxTransformer::new(|x: i32| x.to_string());
1770    ///
1771    /// // Clone to preserve original
1772    /// let composed = add.and_then(to_string.clone());
1773    /// assert_eq!(composed.apply(20, 22), "42");
1774    ///
1775    /// // Original still usable
1776    /// assert_eq!(to_string.apply(10), "10");
1777    /// ```
1778    fn and_then<S, F>(self, after: F) -> BoxBiTransformer<T, U, S>
1779    where
1780        S: 'static,
1781        F: crate::transformer::Transformer<R, S> + 'static,
1782        T: 'static,
1783        U: 'static,
1784        R: 'static,
1785    {
1786        BoxBiTransformer::new(move |t: T, u: U| after.apply(self(t, u)))
1787    }
1788
1789    /// Creates a conditional bi-transformer
1790    ///
1791    /// Returns a bi-transformer that only executes when a bi-predicate is
1792    /// satisfied. You must call `or_else()` to provide an alternative
1793    /// bi-transformer for when the condition is not satisfied.
1794    ///
1795    /// # Parameters
1796    ///
1797    /// * `predicate` - The condition to check. **Note: This parameter is passed
1798    ///   by value and will transfer ownership.** If you need to preserve the
1799    ///   original bi-predicate, clone it first (if it implements `Clone`).
1800    ///   Can be:
1801    ///   - A closure: `|x: &T, y: &U| -> bool`
1802    ///   - A function pointer: `fn(&T, &U) -> bool`
1803    ///   - A `BoxBiPredicate<T, U>`
1804    ///   - An `RcBiPredicate<T, U>`
1805    ///   - An `ArcBiPredicate<T, U>`
1806    ///   - Any type implementing `BiPredicate<T, U>`
1807    ///
1808    /// # Returns
1809    ///
1810    /// Returns `BoxConditionalBiTransformer<T, U, R>`
1811    ///
1812    /// # Examples
1813    ///
1814    /// ## Basic usage with or_else
1815    ///
1816    /// ```rust
1817    /// use prism3_function::{BiTransformer, FnBiTransformerOps};
1818    ///
1819    /// let add = |x: i32, y: i32| x + y;
1820    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0)
1821    ///     .or_else(|x: i32, y: i32| x * y);
1822    ///
1823    /// assert_eq!(conditional.apply(5, 3), 8);
1824    /// assert_eq!(conditional.apply(-5, 3), -15);
1825    /// ```
1826    ///
1827    /// ## Preserving bi-predicate with clone
1828    ///
1829    /// ```rust
1830    /// use prism3_function::{BiTransformer, FnBiTransformerOps,
1831    ///     RcBiPredicate};
1832    ///
1833    /// let add = |x: i32, y: i32| x + y;
1834    /// let both_positive = RcBiPredicate::new(|x: &i32, y: &i32|
1835    ///     *x > 0 && *y > 0);
1836    ///
1837    /// // Clone to preserve original bi-predicate
1838    /// let conditional = add.when(both_positive.clone())
1839    ///     .or_else(|x: i32, y: i32| x * y);
1840    ///
1841    /// assert_eq!(conditional.apply(5, 3), 8);
1842    ///
1843    /// // Original bi-predicate still usable
1844    /// assert!(both_positive.test(&5, &3));
1845    /// ```
1846    fn when<P>(self, predicate: P) -> BoxConditionalBiTransformer<T, U, R>
1847    where
1848        P: BiPredicate<T, U> + 'static,
1849        T: 'static,
1850        U: 'static,
1851        R: 'static,
1852    {
1853        BoxBiTransformer::new(self).when(predicate)
1854    }
1855}
1856
1857/// Blanket implementation of FnBiTransformerOps for all closures
1858///
1859/// Automatically implements `FnBiTransformerOps<T, U, R>` for any type that
1860/// implements `Fn(T, U) -> R`.
1861///
1862/// # Author
1863///
1864/// Hu Haixing
1865impl<T, U, R, F> FnBiTransformerOps<T, U, R> for F where F: Fn(T, U) -> R + 'static {}
1866
1867// ============================================================================
1868// BinaryOperator Trait - Marker trait for BiTransformer<T, T, T>
1869// ============================================================================
1870
1871/// BinaryOperator trait - marker trait for binary operators
1872///
1873/// A binary operator takes two values of type `T` and produces a value of the
1874/// same type `T`. This trait extends `BiTransformer<T, T, T>` to provide
1875/// semantic clarity for same-type binary operations. Equivalent to Java's
1876/// `BinaryOperator<T>` which extends `BiFunction<T, T, T>`.
1877///
1878/// # Automatic Implementation
1879///
1880/// This trait is automatically implemented for all types that implement
1881/// `BiTransformer<T, T, T>`, so you don't need to implement it manually.
1882///
1883/// # Type Parameters
1884///
1885/// * `T` - The type of both input values and the output value
1886///
1887/// # Examples
1888///
1889/// ## Using in generic constraints
1890///
1891/// ```rust
1892/// use prism3_function::{BinaryOperator, BiTransformer};
1893///
1894/// fn reduce<T, O>(values: Vec<T>, initial: T, op: O) -> T
1895/// where
1896///     O: BinaryOperator<T>,
1897///     T: Clone,
1898/// {
1899///     values.into_iter().fold(initial, |acc, val| op.apply(acc, val))
1900/// }
1901///
1902/// let sum = |a: i32, b: i32| a + b;
1903/// assert_eq!(reduce(vec![1, 2, 3, 4], 0, sum), 10);
1904/// ```
1905///
1906/// ## With concrete types
1907///
1908/// ```rust
1909/// use prism3_function::{BoxBinaryOperator, BinaryOperator, BiTransformer};
1910///
1911/// fn create_adder() -> BoxBinaryOperator<i32> {
1912///     BoxBinaryOperator::new(|x, y| x + y)
1913/// }
1914///
1915/// let op = create_adder();
1916/// assert_eq!(op.apply(20, 22), 42);
1917/// ```
1918///
1919/// # Author
1920///
1921/// Hu Haixing
1922pub trait BinaryOperator<T>: BiTransformer<T, T, T> {}
1923
1924/// Blanket implementation of BinaryOperator for all BiTransformer<T, T, T>
1925///
1926/// This automatically implements `BinaryOperator<T>` for any type that
1927/// implements `BiTransformer<T, T, T>`.
1928///
1929/// # Author
1930///
1931/// Hu Haixing
1932impl<F, T> BinaryOperator<T> for F
1933where
1934    F: BiTransformer<T, T, T>,
1935    T: 'static,
1936{
1937    // empty
1938}
1939
1940// ============================================================================
1941// Type Aliases for BinaryOperator (BiTransformer<T, T, T>)
1942// ============================================================================
1943
1944/// Type alias for `BoxBiTransformer<T, T, T>`
1945///
1946/// Represents a binary operator that takes two values of type `T` and produces
1947/// a value of the same type `T`, with single ownership semantics. Equivalent to
1948/// Java's `BinaryOperator<T>`.
1949///
1950/// # Examples
1951///
1952/// ```rust
1953/// use prism3_function::{BoxBinaryOperator, BiTransformer};
1954///
1955/// let add: BoxBinaryOperator<i32> = BoxBinaryOperator::new(|x, y| x + y);
1956/// assert_eq!(add.apply(20, 22), 42);
1957/// ```
1958///
1959/// # Author
1960///
1961/// Hu Haixing
1962pub type BoxBinaryOperator<T> = BoxBiTransformer<T, T, T>;
1963
1964/// Type alias for `ArcBiTransformer<T, T, T>`
1965///
1966/// Represents a thread-safe binary operator that takes two values of type `T`
1967/// and produces a value of the same type `T`. Equivalent to Java's
1968/// `BinaryOperator<T>` with shared, thread-safe ownership.
1969///
1970/// # Examples
1971///
1972/// ```rust
1973/// use prism3_function::{ArcBinaryOperator, BiTransformer};
1974///
1975/// let multiply: ArcBinaryOperator<i32> = ArcBinaryOperator::new(|x, y| x * y);
1976/// let multiply_clone = multiply.clone();
1977/// assert_eq!(multiply.apply(6, 7), 42);
1978/// assert_eq!(multiply_clone.apply(6, 7), 42);
1979/// ```
1980///
1981/// # Author
1982///
1983/// Hu Haixing
1984pub type ArcBinaryOperator<T> = ArcBiTransformer<T, T, T>;
1985
1986/// Type alias for `RcBiTransformer<T, T, T>`
1987///
1988/// Represents a single-threaded binary operator that takes two values of type
1989/// `T` and produces a value of the same type `T`. Equivalent to Java's
1990/// `BinaryOperator<T>` with shared, single-threaded ownership.
1991///
1992/// # Examples
1993///
1994/// ```rust
1995/// use prism3_function::{RcBinaryOperator, BiTransformer};
1996///
1997/// let max: RcBinaryOperator<i32> = RcBinaryOperator::new(|x, y| if x > y { x } else { y });
1998/// let max_clone = max.clone();
1999/// assert_eq!(max.apply(30, 42), 42);
2000/// assert_eq!(max_clone.apply(30, 42), 42);
2001/// ```
2002///
2003/// # Author
2004///
2005/// Hu Haixing
2006pub type RcBinaryOperator<T> = RcBiTransformer<T, T, T>;