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// BoxConditionalBiTransformer - Box-based Conditional BiTransformer
465// ============================================================================
466
467/// BoxConditionalBiTransformer struct
468///
469/// A conditional bi-transformer that only executes when a bi-predicate is
470/// satisfied. Uses `BoxBiTransformer` and `BoxBiPredicate` for single
471/// ownership semantics.
472///
473/// This type is typically created by calling `BoxBiTransformer::when()` and is
474/// designed to work with the `or_else()` method to create if-then-else logic.
475///
476/// # Features
477///
478/// - **Single Ownership**: Not cloneable, consumes `self` on use
479/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
480/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
481/// - **Implements BiTransformer**: Can be used anywhere a `BiTransformer` is expected
482///
483/// # Examples
484///
485/// ## With or_else Branch
486///
487/// ```rust
488/// use prism3_function::{BiTransformer, BoxBiTransformer};
489///
490/// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
491/// let multiply = BoxBiTransformer::new(|x: i32, y: i32| x * y);
492/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
493///
494/// assert_eq!(conditional.apply(5, 3), 8);  // when branch executed
495/// assert_eq!(conditional.apply(-5, 3), -15); // or_else branch executed
496/// ```
497///
498/// # Author
499///
500/// Haixing Hu
501pub struct BoxConditionalBiTransformer<T, U, R> {
502    transformer: BoxBiTransformer<T, U, R>,
503    predicate: BoxBiPredicate<T, U>,
504}
505
506impl<T, U, R> BoxConditionalBiTransformer<T, U, R>
507where
508    T: 'static,
509    U: 'static,
510    R: 'static,
511{
512    /// Adds an else branch
513    ///
514    /// Executes the original bi-transformer when the condition is satisfied,
515    /// otherwise executes else_transformer.
516    ///
517    /// # Parameters
518    ///
519    /// * `else_transformer` - The bi-transformer for the else branch, can be:
520    ///   - Closure: `|x: T, y: U| -> R`
521    ///   - `BoxBiTransformer<T, U, R>`, `RcBiTransformer<T, U, R>`, `ArcBiTransformer<T, U, R>`
522    ///   - Any type implementing `BiTransformer<T, U, R>`
523    ///
524    /// # Returns
525    ///
526    /// Returns the composed `BoxBiTransformer<T, U, R>`
527    ///
528    /// # Examples
529    ///
530    /// ## Using a closure (recommended)
531    ///
532    /// ```rust
533    /// use prism3_function::{BiTransformer, BoxBiTransformer};
534    ///
535    /// let add = BoxBiTransformer::new(|x: i32, y: i32| x + y);
536    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(|x: i32, y: i32| x * y);
537    ///
538    /// assert_eq!(conditional.apply(5, 3), 8);   // Condition satisfied, execute add
539    /// assert_eq!(conditional.apply(-5, 3), -15); // Condition not satisfied, execute multiply
540    /// ```
541    pub fn or_else<F>(self, else_transformer: F) -> BoxBiTransformer<T, U, R>
542    where
543        F: BiTransformer<T, U, R> + 'static,
544    {
545        let pred = self.predicate;
546        let then_trans = self.transformer;
547        BoxBiTransformer::new(move |t, u| {
548            if pred.test(&t, &u) {
549                then_trans.apply(t, u)
550            } else {
551                else_transformer.apply(t, u)
552            }
553        })
554    }
555}
556
557// ============================================================================
558// ArcBiTransformer - Arc<dyn Fn(T, U) -> R + Send + Sync>
559// ============================================================================
560
561/// ArcBiTransformer - thread-safe bi-transformer wrapper
562///
563/// A thread-safe, clonable bi-transformer wrapper suitable for multi-threaded
564/// scenarios. Can be called multiple times and shared across threads.
565///
566/// # Features
567///
568/// - **Based on**: `Arc<dyn Fn(T, U) -> R + Send + Sync>`
569/// - **Ownership**: Shared ownership via reference counting
570/// - **Reusability**: Can be called multiple times (each call consumes its
571///   inputs)
572/// - **Thread Safety**: Thread-safe (`Send + Sync` required)
573/// - **Clonable**: Cheap cloning via `Arc::clone`
574///
575/// # Author
576///
577/// Hu Haixing
578pub struct ArcBiTransformer<T, U, R> {
579    function: Arc<dyn Fn(T, U) -> R + Send + Sync>,
580}
581
582impl<T, U, R> ArcBiTransformer<T, U, R>
583where
584    T: Send + Sync + 'static,
585    U: Send + Sync + 'static,
586    R: 'static,
587{
588    /// Creates a new ArcBiTransformer
589    ///
590    /// # Parameters
591    ///
592    /// * `f` - The closure or function to wrap (must be Send + Sync)
593    ///
594    /// # Examples
595    ///
596    /// ```rust
597    /// use prism3_function::{ArcBiTransformer, BiTransformer};
598    ///
599    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
600    /// assert_eq!(add.apply(20, 22), 42);
601    /// ```
602    pub fn new<F>(f: F) -> Self
603    where
604        F: Fn(T, U) -> R + Send + Sync + 'static,
605    {
606        ArcBiTransformer {
607            function: Arc::new(f),
608        }
609    }
610
611    /// Chain composition - applies self first, then after
612    ///
613    /// Creates a new bi-transformer that applies this bi-transformer first,
614    /// then applies the after transformer to the result. Uses &self, so original
615    /// bi-transformer remains usable.
616    ///
617    /// # Type Parameters
618    ///
619    /// * `S` - The output type of the after transformer
620    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
621    ///
622    /// # Parameters
623    ///
624    /// * `after` - The transformer to apply after self. **Note: This parameter
625    ///   is passed by value and will transfer ownership.** If you need to
626    ///   preserve the original transformer, clone it first (if it implements
627    ///   `Clone`). Must be `Send + Sync`, can be:
628    ///   - A closure: `|x: R| -> S` (must be `Send + Sync`)
629    ///   - A function pointer: `fn(R) -> S`
630    ///   - A `BoxTransformer<R, S>`
631    ///   - An `RcTransformer<R, S>`
632    ///   - An `ArcTransformer<R, S>` (will be moved)
633    ///   - Any type implementing `Transformer<R, S> + Send + Sync`
634    ///
635    /// # Returns
636    ///
637    /// A new `ArcBiTransformer<T, U, S>` representing the composition
638    ///
639    /// # Examples
640    ///
641    /// ## Direct value passing (ownership transfer)
642    ///
643    /// ```rust
644    /// use prism3_function::{BiTransformer, ArcBiTransformer, ArcTransformer};
645    ///
646    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
647    /// let double = ArcTransformer::new(|x: i32| x * 2);
648    ///
649    /// // double is moved here
650    /// let composed = add.and_then(double);
651    ///
652    /// // Original add bi-transformer still usable (uses &self)
653    /// assert_eq!(add.apply(20, 22), 42);
654    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
655    /// // double.apply(10); // Would not compile - moved
656    /// ```
657    ///
658    /// ## Preserving original with clone
659    ///
660    /// ```rust
661    /// use prism3_function::{BiTransformer, ArcBiTransformer, ArcTransformer};
662    ///
663    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
664    /// let double = ArcTransformer::new(|x: i32| x * 2);
665    ///
666    /// // Clone to preserve original
667    /// let composed = add.and_then(double.clone());
668    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
669    ///
670    /// // Both originals still usable
671    /// assert_eq!(add.apply(20, 22), 42);
672    /// assert_eq!(double.apply(10), 20);
673    /// ```
674    pub fn and_then<S, F>(&self, after: F) -> ArcBiTransformer<T, U, S>
675    where
676        S: Send + Sync + 'static,
677        F: crate::transformer::Transformer<R, S> + Send + Sync + 'static,
678    {
679        let self_clone = Arc::clone(&self.function);
680        ArcBiTransformer {
681            function: Arc::new(move |t: T, u: U| after.apply(self_clone(t, u))),
682        }
683    }
684
685    /// Creates a conditional bi-transformer (thread-safe version)
686    ///
687    /// Returns a bi-transformer that only executes when a bi-predicate is
688    /// satisfied. You must call `or_else()` to provide an alternative
689    /// bi-transformer.
690    ///
691    /// # Parameters
692    ///
693    /// * `predicate` - The condition to check. **Note: This parameter is passed
694    ///   by value and will transfer ownership.** If you need to preserve the
695    ///   original bi-predicate, clone it first (if it implements `Clone`).
696    ///   Must be `Send + Sync`, can be:
697    ///   - A closure: `|x: &T, y: &U| -> bool` (requires `Send + Sync`)
698    ///   - A function pointer: `fn(&T, &U) -> bool`
699    ///   - An `ArcBiPredicate<T, U>`
700    ///   - Any type implementing `BiPredicate<T, U> + Send + Sync`
701    ///
702    /// # Returns
703    ///
704    /// Returns `ArcConditionalBiTransformer<T, U, R>`
705    ///
706    /// # Examples
707    ///
708    /// ## Basic usage with or_else
709    ///
710    /// ```rust
711    /// use prism3_function::{BiTransformer, ArcBiTransformer};
712    ///
713    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
714    /// let multiply = ArcBiTransformer::new(|x: i32, y: i32| x * y);
715    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
716    ///     .or_else(multiply);
717    ///
718    /// let conditional_clone = conditional.clone();
719    ///
720    /// assert_eq!(conditional.apply(5, 3), 8);
721    /// assert_eq!(conditional_clone.apply(-5, 3), -15);
722    /// ```
723    ///
724    /// ## Preserving bi-predicate with clone
725    ///
726    /// ```rust
727    /// use prism3_function::{BiTransformer, ArcBiTransformer, ArcBiPredicate};
728    ///
729    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
730    /// let both_positive = ArcBiPredicate::new(|x: &i32, y: &i32|
731    ///     *x > 0 && *y > 0);
732    ///
733    /// // Clone to preserve original bi-predicate
734    /// let conditional = add.when(both_positive.clone())
735    ///     .or_else(ArcBiTransformer::new(|x, y| x * y));
736    ///
737    /// assert_eq!(conditional.apply(5, 3), 8);
738    ///
739    /// // Original bi-predicate still usable
740    /// assert!(both_positive.test(&5, &3));
741    /// ```
742    pub fn when<P>(&self, predicate: P) -> ArcConditionalBiTransformer<T, U, R>
743    where
744        P: BiPredicate<T, U> + Send + Sync + 'static,
745    {
746        ArcConditionalBiTransformer {
747            transformer: self.clone(),
748            predicate: predicate.into_arc(),
749        }
750    }
751}
752
753impl<T, U, R> ArcBiTransformer<T, U, R>
754where
755    T: Send + Sync + 'static,
756    U: Send + Sync + 'static,
757    R: Clone + 'static,
758{
759    /// Creates a constant bi-transformer
760    ///
761    /// # Examples
762    ///
763    /// ```rust
764    /// use prism3_function::{ArcBiTransformer, BiTransformer};
765    ///
766    /// let constant = ArcBiTransformer::constant("hello");
767    /// assert_eq!(constant.apply(123, 456), "hello");
768    /// ```
769    pub fn constant(value: R) -> ArcBiTransformer<T, U, R>
770    where
771        R: Send + Sync,
772    {
773        ArcBiTransformer::new(move |_, _| value.clone())
774    }
775}
776
777impl<T, U, R> BiTransformer<T, U, R> for ArcBiTransformer<T, U, R> {
778    fn apply(&self, first: T, second: U) -> R {
779        (self.function)(first, second)
780    }
781
782    fn into_box(self) -> BoxBiTransformer<T, U, R>
783    where
784        T: 'static,
785        U: 'static,
786        R: 'static,
787    {
788        BoxBiTransformer::new(move |t, u| (self.function)(t, u))
789    }
790
791    fn into_rc(self) -> RcBiTransformer<T, U, R>
792    where
793        T: 'static,
794        U: 'static,
795        R: 'static,
796    {
797        RcBiTransformer::new(move |t, u| (self.function)(t, u))
798    }
799
800    fn into_arc(self) -> ArcBiTransformer<T, U, R>
801    where
802        T: Send + Sync + 'static,
803        U: Send + Sync + 'static,
804        R: Send + Sync + 'static,
805    {
806        // Zero-cost: directly return itself
807        self
808    }
809
810    fn into_fn(self) -> impl Fn(T, U) -> R
811    where
812        T: 'static,
813        U: 'static,
814        R: 'static,
815    {
816        move |t: T, u: U| (self.function)(t, u)
817    }
818
819    fn to_box(&self) -> BoxBiTransformer<T, U, R>
820    where
821        T: 'static,
822        U: 'static,
823        R: 'static,
824    {
825        let self_fn = self.function.clone();
826        BoxBiTransformer::new(move |t, u| self_fn(t, u))
827    }
828
829    fn to_rc(&self) -> RcBiTransformer<T, U, R>
830    where
831        T: 'static,
832        U: 'static,
833        R: 'static,
834    {
835        let self_fn = self.function.clone();
836        RcBiTransformer::new(move |t, u| self_fn(t, u))
837    }
838
839    fn to_arc(&self) -> ArcBiTransformer<T, U, R>
840    where
841        T: Send + Sync + 'static,
842        U: Send + Sync + 'static,
843        R: Send + Sync + 'static,
844    {
845        self.clone()
846    }
847
848    fn to_fn(&self) -> impl Fn(T, U) -> R
849    where
850        T: 'static,
851        U: 'static,
852        R: 'static,
853    {
854        let self_fn = self.function.clone();
855        move |t: T, u: U| self_fn(t, u)
856    }
857}
858
859impl<T, U, R> Clone for ArcBiTransformer<T, U, R> {
860    fn clone(&self) -> Self {
861        ArcBiTransformer {
862            function: Arc::clone(&self.function),
863        }
864    }
865}
866
867// ============================================================================
868// ArcConditionalBiTransformer - Arc-based Conditional BiTransformer
869// ============================================================================
870
871/// ArcConditionalBiTransformer struct
872///
873/// A thread-safe conditional bi-transformer that only executes when a
874/// bi-predicate is satisfied. Uses `ArcBiTransformer` and `ArcBiPredicate` for
875/// shared ownership across threads.
876///
877/// This type is typically created by calling `ArcBiTransformer::when()` and is
878/// designed to work with the `or_else()` method to create if-then-else logic.
879///
880/// # Features
881///
882/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
883/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
884/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
885/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
886///
887/// # Examples
888///
889/// ```rust
890/// use prism3_function::{BiTransformer, ArcBiTransformer};
891///
892/// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
893/// let multiply = ArcBiTransformer::new(|x: i32, y: i32| x * y);
894/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
895///
896/// let conditional_clone = conditional.clone();
897///
898/// assert_eq!(conditional.apply(5, 3), 8);
899/// assert_eq!(conditional_clone.apply(-5, 3), -15);
900/// ```
901///
902/// # Author
903///
904/// Haixing Hu
905pub struct ArcConditionalBiTransformer<T, U, R> {
906    transformer: ArcBiTransformer<T, U, R>,
907    predicate: ArcBiPredicate<T, U>,
908}
909
910impl<T, U, R> ArcConditionalBiTransformer<T, U, R>
911where
912    T: Send + Sync + 'static,
913    U: Send + Sync + 'static,
914    R: 'static,
915{
916    /// Adds an else branch (thread-safe version)
917    ///
918    /// Executes the original bi-transformer when the condition is satisfied,
919    /// otherwise executes else_transformer.
920    ///
921    /// # Parameters
922    ///
923    /// * `else_transformer` - The bi-transformer for the else branch, can be:
924    ///   - Closure: `|x: T, y: U| -> R` (must be `Send + Sync`)
925    ///   - `ArcBiTransformer<T, U, R>`, `BoxBiTransformer<T, U, R>`
926    ///   - Any type implementing `BiTransformer<T, U, R> + Send + Sync`
927    ///
928    /// # Returns
929    ///
930    /// Returns the composed `ArcBiTransformer<T, U, R>`
931    ///
932    /// # Examples
933    ///
934    /// ## Using a closure (recommended)
935    ///
936    /// ```rust
937    /// use prism3_function::{BiTransformer, ArcBiTransformer};
938    ///
939    /// let add = ArcBiTransformer::new(|x: i32, y: i32| x + y);
940    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(|x: i32, y: i32| x * y);
941    ///
942    /// assert_eq!(conditional.apply(5, 3), 8);
943    /// assert_eq!(conditional.apply(-5, 3), -15);
944    /// ```
945    pub fn or_else<F>(&self, else_transformer: F) -> ArcBiTransformer<T, U, R>
946    where
947        F: BiTransformer<T, U, R> + Send + Sync + 'static,
948        R: Send + Sync,
949    {
950        let pred = self.predicate.clone();
951        let then_trans = self.transformer.clone();
952        ArcBiTransformer::new(move |t, u| {
953            if pred.test(&t, &u) {
954                then_trans.apply(t, u)
955            } else {
956                else_transformer.apply(t, u)
957            }
958        })
959    }
960}
961
962impl<T, U, R> Clone for ArcConditionalBiTransformer<T, U, R> {
963    /// Clones the conditional bi-transformer
964    ///
965    /// Creates a new instance that shares the underlying bi-transformer and
966    /// bi-predicate with the original instance.
967    fn clone(&self) -> Self {
968        ArcConditionalBiTransformer {
969            transformer: self.transformer.clone(),
970            predicate: self.predicate.clone(),
971        }
972    }
973}
974
975// ============================================================================
976// RcBiTransformer - Rc<dyn Fn(T, U) -> R>
977// ============================================================================
978
979/// RcBiTransformer - single-threaded bi-transformer wrapper
980///
981/// A single-threaded, clonable bi-transformer wrapper optimized for scenarios
982/// that require sharing without thread-safety overhead.
983///
984/// # Features
985///
986/// - **Based on**: `Rc<dyn Fn(T, U) -> R>`
987/// - **Ownership**: Shared ownership via reference counting (non-atomic)
988/// - **Reusability**: Can be called multiple times (each call consumes its
989///   inputs)
990/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
991/// - **Clonable**: Cheap cloning via `Rc::clone`
992///
993/// # Author
994///
995/// Hu Haixing
996pub struct RcBiTransformer<T, U, R> {
997    function: Rc<dyn Fn(T, U) -> R>,
998}
999
1000impl<T, U, R> RcBiTransformer<T, U, R>
1001where
1002    T: 'static,
1003    U: 'static,
1004    R: 'static,
1005{
1006    /// Creates a new RcBiTransformer
1007    ///
1008    /// # Parameters
1009    ///
1010    /// * `f` - The closure or function to wrap
1011    ///
1012    /// # Examples
1013    ///
1014    /// ```rust
1015    /// use prism3_function::{RcBiTransformer, BiTransformer};
1016    ///
1017    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1018    /// assert_eq!(add.apply(20, 22), 42);
1019    /// ```
1020    pub fn new<F>(f: F) -> Self
1021    where
1022        F: Fn(T, U) -> R + 'static,
1023    {
1024        RcBiTransformer {
1025            function: Rc::new(f),
1026        }
1027    }
1028
1029    /// Chain composition - applies self first, then after
1030    ///
1031    /// Creates a new bi-transformer that applies this bi-transformer first,
1032    /// then applies the after transformer to the result. Uses &self, so original
1033    /// bi-transformer remains usable.
1034    ///
1035    /// # Type Parameters
1036    ///
1037    /// * `S` - The output type of the after transformer
1038    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
1039    ///
1040    /// # Parameters
1041    ///
1042    /// * `after` - The transformer to apply after self. **Note: This parameter
1043    ///   is passed by value and will transfer ownership.** If you need to
1044    ///   preserve the original transformer, clone it first (if it implements
1045    ///   `Clone`). Can be:
1046    ///   - A closure: `|x: R| -> S`
1047    ///   - A function pointer: `fn(R) -> S`
1048    ///   - A `BoxTransformer<R, S>`
1049    ///   - An `RcTransformer<R, S>` (will be moved)
1050    ///   - An `ArcTransformer<R, S>`
1051    ///   - Any type implementing `Transformer<R, S>`
1052    ///
1053    /// # Returns
1054    ///
1055    /// A new `RcBiTransformer<T, U, S>` representing the composition
1056    ///
1057    /// # Examples
1058    ///
1059    /// ## Direct value passing (ownership transfer)
1060    ///
1061    /// ```rust
1062    /// use prism3_function::{BiTransformer, RcBiTransformer, RcTransformer};
1063    ///
1064    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1065    /// let double = RcTransformer::new(|x: i32| x * 2);
1066    ///
1067    /// // double is moved here
1068    /// let composed = add.and_then(double);
1069    ///
1070    /// // Original add bi-transformer still usable (uses &self)
1071    /// assert_eq!(add.apply(20, 22), 42);
1072    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
1073    /// // double.apply(10); // Would not compile - moved
1074    /// ```
1075    ///
1076    /// ## Preserving original with clone
1077    ///
1078    /// ```rust
1079    /// use prism3_function::{BiTransformer, RcBiTransformer, RcTransformer};
1080    ///
1081    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1082    /// let double = RcTransformer::new(|x: i32| x * 2);
1083    ///
1084    /// // Clone to preserve original
1085    /// let composed = add.and_then(double.clone());
1086    /// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
1087    ///
1088    /// // Both originals still usable
1089    /// assert_eq!(add.apply(20, 22), 42);
1090    /// assert_eq!(double.apply(10), 20);
1091    /// ```
1092    pub fn and_then<S, F>(&self, after: F) -> RcBiTransformer<T, U, S>
1093    where
1094        S: 'static,
1095        F: crate::transformer::Transformer<R, S> + 'static,
1096    {
1097        let self_clone = Rc::clone(&self.function);
1098        RcBiTransformer {
1099            function: Rc::new(move |t: T, u: U| after.apply(self_clone(t, u))),
1100        }
1101    }
1102
1103    /// Creates a conditional bi-transformer (single-threaded shared version)
1104    ///
1105    /// Returns a bi-transformer that only executes when a bi-predicate is
1106    /// satisfied. You must call `or_else()` to provide an alternative
1107    /// bi-transformer.
1108    ///
1109    /// # Parameters
1110    ///
1111    /// * `predicate` - The condition to check. **Note: This parameter is passed
1112    ///   by value and will transfer ownership.** If you need to preserve the
1113    ///   original bi-predicate, clone it first (if it implements `Clone`).
1114    ///   Can be:
1115    ///   - A closure: `|x: &T, y: &U| -> bool`
1116    ///   - A function pointer: `fn(&T, &U) -> bool`
1117    ///   - A `BoxBiPredicate<T, U>`
1118    ///   - An `RcBiPredicate<T, U>`
1119    ///   - An `ArcBiPredicate<T, U>`
1120    ///   - Any type implementing `BiPredicate<T, U>`
1121    ///
1122    /// # Returns
1123    ///
1124    /// Returns `RcConditionalBiTransformer<T, U, R>`
1125    ///
1126    /// # Examples
1127    ///
1128    /// ## Basic usage with or_else
1129    ///
1130    /// ```rust
1131    /// use prism3_function::{BiTransformer, RcBiTransformer};
1132    ///
1133    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1134    /// let multiply = RcBiTransformer::new(|x: i32, y: i32| x * y);
1135    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
1136    ///     .or_else(multiply);
1137    ///
1138    /// let conditional_clone = conditional.clone();
1139    ///
1140    /// assert_eq!(conditional.apply(5, 3), 8);
1141    /// assert_eq!(conditional_clone.apply(-5, 3), -15);
1142    /// ```
1143    ///
1144    /// ## Preserving bi-predicate with clone
1145    ///
1146    /// ```rust
1147    /// use prism3_function::{BiTransformer, RcBiTransformer, RcBiPredicate};
1148    ///
1149    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1150    /// let both_positive = RcBiPredicate::new(|x: &i32, y: &i32|
1151    ///     *x > 0 && *y > 0);
1152    ///
1153    /// // Clone to preserve original bi-predicate
1154    /// let conditional = add.when(both_positive.clone())
1155    ///     .or_else(RcBiTransformer::new(|x, y| x * y));
1156    ///
1157    /// assert_eq!(conditional.apply(5, 3), 8);
1158    ///
1159    /// // Original bi-predicate still usable
1160    /// assert!(both_positive.test(&5, &3));
1161    /// ```
1162    pub fn when<P>(&self, predicate: P) -> RcConditionalBiTransformer<T, U, R>
1163    where
1164        P: BiPredicate<T, U> + 'static,
1165    {
1166        RcConditionalBiTransformer {
1167            transformer: self.clone(),
1168            predicate: predicate.into_rc(),
1169        }
1170    }
1171}
1172
1173impl<T, U, R> RcBiTransformer<T, U, R>
1174where
1175    T: 'static,
1176    U: 'static,
1177    R: Clone + 'static,
1178{
1179    /// Creates a constant bi-transformer
1180    ///
1181    /// # Examples
1182    ///
1183    /// ```rust
1184    /// use prism3_function::{RcBiTransformer, BiTransformer};
1185    ///
1186    /// let constant = RcBiTransformer::constant("hello");
1187    /// assert_eq!(constant.apply(123, 456), "hello");
1188    /// ```
1189    pub fn constant(value: R) -> RcBiTransformer<T, U, R> {
1190        RcBiTransformer::new(move |_, _| value.clone())
1191    }
1192}
1193
1194impl<T, U, R> BiTransformer<T, U, R> for RcBiTransformer<T, U, R> {
1195    fn apply(&self, first: T, second: U) -> R {
1196        (self.function)(first, second)
1197    }
1198
1199    fn into_box(self) -> BoxBiTransformer<T, U, R>
1200    where
1201        T: 'static,
1202        U: 'static,
1203        R: 'static,
1204    {
1205        BoxBiTransformer::new(move |t, u| (self.function)(t, u))
1206    }
1207
1208    fn into_rc(self) -> RcBiTransformer<T, U, R>
1209    where
1210        T: 'static,
1211        U: 'static,
1212        R: 'static,
1213    {
1214        // Zero-cost: directly return itself
1215        self
1216    }
1217
1218    // do NOT override RcBiTransformer::into_arc() because RcBiTransformer is not Send + Sync
1219    // and calling RcBiTransformer::into_arc() will cause a compile error
1220
1221    fn into_fn(self) -> impl Fn(T, U) -> R
1222    where
1223        T: 'static,
1224        U: 'static,
1225        R: 'static,
1226    {
1227        move |t: T, u: U| (self.function)(t, u)
1228    }
1229
1230    fn to_box(&self) -> BoxBiTransformer<T, U, R>
1231    where
1232        T: 'static,
1233        U: 'static,
1234        R: 'static,
1235    {
1236        let self_fn = self.function.clone();
1237        BoxBiTransformer::new(move |t, u| self_fn(t, u))
1238    }
1239
1240    fn to_rc(&self) -> RcBiTransformer<T, U, R>
1241    where
1242        T: 'static,
1243        U: 'static,
1244        R: 'static,
1245    {
1246        self.clone()
1247    }
1248
1249    // do NOT override RcBiTransformer::to_arc() because RcBiTransformer is not Send + Sync
1250    // and calling RcBiTransformer::to_arc() will cause a compile error
1251
1252    fn to_fn(&self) -> impl Fn(T, U) -> R
1253    where
1254        T: 'static,
1255        U: 'static,
1256        R: 'static,
1257    {
1258        let self_fn = self.function.clone();
1259        move |t: T, u: U| self_fn(t, u)
1260    }
1261}
1262
1263impl<T, U, R> Clone for RcBiTransformer<T, U, R> {
1264    fn clone(&self) -> Self {
1265        RcBiTransformer {
1266            function: Rc::clone(&self.function),
1267        }
1268    }
1269}
1270
1271// ============================================================================
1272// RcConditionalBiTransformer - Rc-based Conditional BiTransformer
1273// ============================================================================
1274
1275/// RcConditionalBiTransformer struct
1276///
1277/// A single-threaded conditional bi-transformer that only executes when a
1278/// bi-predicate is satisfied. Uses `RcBiTransformer` and `RcBiPredicate` for
1279/// shared ownership within a single thread.
1280///
1281/// This type is typically created by calling `RcBiTransformer::when()` and is
1282/// designed to work with the `or_else()` method to create if-then-else logic.
1283///
1284/// # Features
1285///
1286/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
1287/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
1288/// - **Conditional Execution**: Only transforms when bi-predicate returns `true`
1289/// - **No Lock Overhead**: More efficient than `ArcConditionalBiTransformer`
1290///
1291/// # Examples
1292///
1293/// ```rust
1294/// use prism3_function::{BiTransformer, RcBiTransformer};
1295///
1296/// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1297/// let multiply = RcBiTransformer::new(|x: i32, y: i32| x * y);
1298/// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
1299///
1300/// let conditional_clone = conditional.clone();
1301///
1302/// assert_eq!(conditional.apply(5, 3), 8);
1303/// assert_eq!(conditional_clone.apply(-5, 3), -15);
1304/// ```
1305///
1306/// # Author
1307///
1308/// Haixing Hu
1309pub struct RcConditionalBiTransformer<T, U, R> {
1310    transformer: RcBiTransformer<T, U, R>,
1311    predicate: RcBiPredicate<T, U>,
1312}
1313
1314impl<T, U, R> RcConditionalBiTransformer<T, U, R>
1315where
1316    T: 'static,
1317    U: 'static,
1318    R: 'static,
1319{
1320    /// Adds an else branch (single-threaded shared version)
1321    ///
1322    /// Executes the original bi-transformer when the condition is satisfied,
1323    /// otherwise executes else_transformer.
1324    ///
1325    /// # Parameters
1326    ///
1327    /// * `else_transformer` - The bi-transformer for the else branch, can be:
1328    ///   - Closure: `|x: T, y: U| -> R`
1329    ///   - `RcBiTransformer<T, U, R>`, `BoxBiTransformer<T, U, R>`
1330    ///   - Any type implementing `BiTransformer<T, U, R>`
1331    ///
1332    /// # Returns
1333    ///
1334    /// Returns the composed `RcBiTransformer<T, U, R>`
1335    ///
1336    /// # Examples
1337    ///
1338    /// ## Using a closure (recommended)
1339    ///
1340    /// ```rust
1341    /// use prism3_function::{BiTransformer, RcBiTransformer};
1342    ///
1343    /// let add = RcBiTransformer::new(|x: i32, y: i32| x + y);
1344    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(|x: i32, y: i32| x * y);
1345    ///
1346    /// assert_eq!(conditional.apply(5, 3), 8);
1347    /// assert_eq!(conditional.apply(-5, 3), -15);
1348    /// ```
1349    pub fn or_else<F>(&self, else_transformer: F) -> RcBiTransformer<T, U, R>
1350    where
1351        F: BiTransformer<T, U, R> + 'static,
1352    {
1353        let pred = self.predicate.clone();
1354        let then_trans = self.transformer.clone();
1355        RcBiTransformer::new(move |t, u| {
1356            if pred.test(&t, &u) {
1357                then_trans.apply(t, u)
1358            } else {
1359                else_transformer.apply(t, u)
1360            }
1361        })
1362    }
1363}
1364
1365impl<T, U, R> Clone for RcConditionalBiTransformer<T, U, R> {
1366    /// Clones the conditional bi-transformer
1367    ///
1368    /// Creates a new instance that shares the underlying bi-transformer and
1369    /// bi-predicate with the original instance.
1370    fn clone(&self) -> Self {
1371        RcConditionalBiTransformer {
1372            transformer: self.transformer.clone(),
1373            predicate: self.predicate.clone(),
1374        }
1375    }
1376}
1377
1378// ============================================================================
1379// Blanket implementation for standard Fn trait
1380// ============================================================================
1381
1382/// Implement BiTransformer<T, U, R> for any type that implements Fn(T, U) -> R
1383///
1384/// This allows closures and function pointers to be used directly with our
1385/// BiTransformer trait without wrapping.
1386///
1387/// # Examples
1388///
1389/// ```rust
1390/// use prism3_function::BiTransformer;
1391///
1392/// fn add(x: i32, y: i32) -> i32 { x + y }
1393///
1394/// assert_eq!(add.apply(20, 22), 42);
1395///
1396/// let multiply = |x: i32, y: i32| x * y;
1397/// assert_eq!(multiply.apply(6, 7), 42);
1398/// ```
1399///
1400/// # Author
1401///
1402/// Hu Haixing
1403impl<F, T, U, R> BiTransformer<T, U, R> for F
1404where
1405    F: Fn(T, U) -> R,
1406    T: 'static,
1407    U: 'static,
1408    R: 'static,
1409{
1410    fn apply(&self, first: T, second: U) -> R {
1411        self(first, second)
1412    }
1413
1414    fn into_box(self) -> BoxBiTransformer<T, U, R>
1415    where
1416        Self: Sized + 'static,
1417    {
1418        BoxBiTransformer::new(self)
1419    }
1420
1421    fn into_rc(self) -> RcBiTransformer<T, U, R>
1422    where
1423        Self: Sized + 'static,
1424    {
1425        RcBiTransformer::new(self)
1426    }
1427
1428    fn into_arc(self) -> ArcBiTransformer<T, U, R>
1429    where
1430        Self: Sized + Send + Sync + 'static,
1431        T: Send + Sync + 'static,
1432        U: Send + Sync + 'static,
1433        R: Send + Sync + 'static,
1434    {
1435        ArcBiTransformer::new(self)
1436    }
1437
1438    fn into_fn(self) -> impl Fn(T, U) -> R
1439    where
1440        Self: Sized + 'static,
1441    {
1442        move |t: T, u: U| self(t, u)
1443    }
1444
1445    fn to_box(&self) -> BoxBiTransformer<T, U, R>
1446    where
1447        Self: Sized + Clone + 'static,
1448        T: 'static,
1449        U: 'static,
1450        R: 'static,
1451    {
1452        BoxBiTransformer::new(self.clone())
1453    }
1454
1455    fn to_rc(&self) -> RcBiTransformer<T, U, R>
1456    where
1457        Self: Sized + Clone + 'static,
1458        T: 'static,
1459        U: 'static,
1460        R: 'static,
1461    {
1462        RcBiTransformer::new(self.clone())
1463    }
1464
1465    fn to_arc(&self) -> ArcBiTransformer<T, U, R>
1466    where
1467        Self: Sized + Clone + Send + Sync + 'static,
1468        T: Send + Sync + 'static,
1469        U: Send + Sync + 'static,
1470        R: Send + Sync + 'static,
1471    {
1472        ArcBiTransformer::new(self.clone())
1473    }
1474
1475    fn to_fn(&self) -> impl Fn(T, U) -> R
1476    where
1477        Self: Sized + Clone + 'static,
1478        T: 'static,
1479        U: 'static,
1480        R: 'static,
1481    {
1482        self.clone()
1483    }
1484}
1485
1486// ============================================================================
1487// FnBiTransformerOps - Extension trait for Fn(T, U) -> R bi-transformers
1488// ============================================================================
1489
1490/// Extension trait for closures implementing `Fn(T, U) -> R`
1491///
1492/// Provides composition methods (`and_then`, `when`) for bi-transformer
1493/// closures and function pointers without requiring explicit wrapping in
1494/// `BoxBiTransformer`.
1495///
1496/// This trait is automatically implemented for all closures and function
1497/// pointers that implement `Fn(T, U) -> R`.
1498///
1499/// # Design Rationale
1500///
1501/// While closures automatically implement `BiTransformer<T, U, R>` through
1502/// blanket implementation, they don't have access to instance methods like
1503/// `and_then` and `when`. This extension trait provides those methods,
1504/// returning `BoxBiTransformer` for maximum flexibility.
1505///
1506/// # Examples
1507///
1508/// ## Chain composition with and_then
1509///
1510/// ```rust
1511/// use prism3_function::{BiTransformer, FnBiTransformerOps};
1512///
1513/// let add = |x: i32, y: i32| x + y;
1514/// let double = |x: i32| x * 2;
1515///
1516/// let composed = add.and_then(double);
1517/// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
1518/// ```
1519///
1520/// ## Conditional execution with when
1521///
1522/// ```rust
1523/// use prism3_function::{BiTransformer, FnBiTransformerOps};
1524///
1525/// let add = |x: i32, y: i32| x + y;
1526/// let multiply = |x: i32, y: i32| x * y;
1527///
1528/// let conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0).or_else(multiply);
1529///
1530/// assert_eq!(conditional.apply(5, 3), 8);   // add
1531/// assert_eq!(conditional.apply(-5, 3), -15); // multiply
1532/// ```
1533///
1534/// # Author
1535///
1536/// Hu Haixing
1537pub trait FnBiTransformerOps<T, U, R>: Fn(T, U) -> R + Sized + 'static {
1538    /// Chain composition - applies self first, then after
1539    ///
1540    /// Creates a new bi-transformer that applies this bi-transformer first,
1541    /// then applies the after transformer to the result. Consumes self and
1542    /// returns a `BoxBiTransformer`.
1543    ///
1544    /// # Type Parameters
1545    ///
1546    /// * `S` - The output type of the after transformer
1547    /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
1548    ///
1549    /// # Parameters
1550    ///
1551    /// * `after` - The transformer to apply after self. **Note: This parameter
1552    ///   is passed by value and will transfer ownership.** If you need to
1553    ///   preserve the original transformer, clone it first (if it implements
1554    ///   `Clone`). Can be:
1555    ///   - A closure: `|x: R| -> S`
1556    ///   - A function pointer: `fn(R) -> S`
1557    ///   - A `BoxTransformer<R, S>`
1558    ///   - An `RcTransformer<R, S>`
1559    ///   - An `ArcTransformer<R, S>`
1560    ///   - Any type implementing `Transformer<R, S>`
1561    ///
1562    /// # Returns
1563    ///
1564    /// A new `BoxBiTransformer<T, U, S>` representing the composition
1565    ///
1566    /// # Examples
1567    ///
1568    /// ## Direct value passing (ownership transfer)
1569    ///
1570    /// ```rust
1571    /// use prism3_function::{BiTransformer, FnBiTransformerOps,
1572    ///     BoxTransformer};
1573    ///
1574    /// let add = |x: i32, y: i32| x + y;
1575    /// let to_string = BoxTransformer::new(|x: i32| x.to_string());
1576    ///
1577    /// // to_string is moved here
1578    /// let composed = add.and_then(to_string);
1579    /// assert_eq!(composed.apply(20, 22), "42");
1580    /// // to_string.apply(10); // Would not compile - moved
1581    /// ```
1582    ///
1583    /// ## Preserving original with clone
1584    ///
1585    /// ```rust
1586    /// use prism3_function::{BiTransformer, FnBiTransformerOps,
1587    ///     BoxTransformer};
1588    ///
1589    /// let add = |x: i32, y: i32| x + y;
1590    /// let to_string = BoxTransformer::new(|x: i32| x.to_string());
1591    ///
1592    /// // Clone to preserve original
1593    /// let composed = add.and_then(to_string.clone());
1594    /// assert_eq!(composed.apply(20, 22), "42");
1595    ///
1596    /// // Original still usable
1597    /// assert_eq!(to_string.apply(10), "10");
1598    /// ```
1599    fn and_then<S, F>(self, after: F) -> BoxBiTransformer<T, U, S>
1600    where
1601        S: 'static,
1602        F: crate::transformer::Transformer<R, S> + 'static,
1603        T: 'static,
1604        U: 'static,
1605        R: 'static,
1606    {
1607        BoxBiTransformer::new(move |t: T, u: U| after.apply(self(t, u)))
1608    }
1609
1610    /// Creates a conditional bi-transformer
1611    ///
1612    /// Returns a bi-transformer that only executes when a bi-predicate is
1613    /// satisfied. You must call `or_else()` to provide an alternative
1614    /// bi-transformer for when the condition is not satisfied.
1615    ///
1616    /// # Parameters
1617    ///
1618    /// * `predicate` - The condition to check. **Note: This parameter is passed
1619    ///   by value and will transfer ownership.** If you need to preserve the
1620    ///   original bi-predicate, clone it first (if it implements `Clone`).
1621    ///   Can be:
1622    ///   - A closure: `|x: &T, y: &U| -> bool`
1623    ///   - A function pointer: `fn(&T, &U) -> bool`
1624    ///   - A `BoxBiPredicate<T, U>`
1625    ///   - An `RcBiPredicate<T, U>`
1626    ///   - An `ArcBiPredicate<T, U>`
1627    ///   - Any type implementing `BiPredicate<T, U>`
1628    ///
1629    /// # Returns
1630    ///
1631    /// Returns `BoxConditionalBiTransformer<T, U, R>`
1632    ///
1633    /// # Examples
1634    ///
1635    /// ## Basic usage with or_else
1636    ///
1637    /// ```rust
1638    /// use prism3_function::{BiTransformer, FnBiTransformerOps};
1639    ///
1640    /// let add = |x: i32, y: i32| x + y;
1641    /// let conditional = add.when(|x: &i32, y: &i32| *x > 0)
1642    ///     .or_else(|x: i32, y: i32| x * y);
1643    ///
1644    /// assert_eq!(conditional.apply(5, 3), 8);
1645    /// assert_eq!(conditional.apply(-5, 3), -15);
1646    /// ```
1647    ///
1648    /// ## Preserving bi-predicate with clone
1649    ///
1650    /// ```rust
1651    /// use prism3_function::{BiTransformer, FnBiTransformerOps,
1652    ///     RcBiPredicate};
1653    ///
1654    /// let add = |x: i32, y: i32| x + y;
1655    /// let both_positive = RcBiPredicate::new(|x: &i32, y: &i32|
1656    ///     *x > 0 && *y > 0);
1657    ///
1658    /// // Clone to preserve original bi-predicate
1659    /// let conditional = add.when(both_positive.clone())
1660    ///     .or_else(|x: i32, y: i32| x * y);
1661    ///
1662    /// assert_eq!(conditional.apply(5, 3), 8);
1663    ///
1664    /// // Original bi-predicate still usable
1665    /// assert!(both_positive.test(&5, &3));
1666    /// ```
1667    fn when<P>(self, predicate: P) -> BoxConditionalBiTransformer<T, U, R>
1668    where
1669        P: BiPredicate<T, U> + 'static,
1670        T: 'static,
1671        U: 'static,
1672        R: 'static,
1673    {
1674        BoxBiTransformer::new(self).when(predicate)
1675    }
1676}
1677
1678/// Blanket implementation of FnBiTransformerOps for all closures
1679///
1680/// Automatically implements `FnBiTransformerOps<T, U, R>` for any type that
1681/// implements `Fn(T, U) -> R`.
1682///
1683/// # Author
1684///
1685/// Hu Haixing
1686impl<T, U, R, F> FnBiTransformerOps<T, U, R> for F where F: Fn(T, U) -> R + 'static {}
1687
1688// ============================================================================
1689// BinaryOperator Trait - Marker trait for BiTransformer<T, T, T>
1690// ============================================================================
1691
1692/// BinaryOperator trait - marker trait for binary operators
1693///
1694/// A binary operator takes two values of type `T` and produces a value of the
1695/// same type `T`. This trait extends `BiTransformer<T, T, T>` to provide
1696/// semantic clarity for same-type binary operations. Equivalent to Java's
1697/// `BinaryOperator<T>` which extends `BiFunction<T, T, T>`.
1698///
1699/// # Automatic Implementation
1700///
1701/// This trait is automatically implemented for all types that implement
1702/// `BiTransformer<T, T, T>`, so you don't need to implement it manually.
1703///
1704/// # Type Parameters
1705///
1706/// * `T` - The type of both input values and the output value
1707///
1708/// # Examples
1709///
1710/// ## Using in generic constraints
1711///
1712/// ```rust
1713/// use prism3_function::{BinaryOperator, BiTransformer};
1714///
1715/// fn reduce<T, O>(values: Vec<T>, initial: T, op: O) -> T
1716/// where
1717///     O: BinaryOperator<T>,
1718///     T: Clone,
1719/// {
1720///     values.into_iter().fold(initial, |acc, val| op.apply(acc, val))
1721/// }
1722///
1723/// let sum = |a: i32, b: i32| a + b;
1724/// assert_eq!(reduce(vec![1, 2, 3, 4], 0, sum), 10);
1725/// ```
1726///
1727/// ## With concrete types
1728///
1729/// ```rust
1730/// use prism3_function::{BoxBinaryOperator, BinaryOperator, BiTransformer};
1731///
1732/// fn create_adder() -> BoxBinaryOperator<i32> {
1733///     BoxBinaryOperator::new(|x, y| x + y)
1734/// }
1735///
1736/// let op = create_adder();
1737/// assert_eq!(op.apply(20, 22), 42);
1738/// ```
1739///
1740/// # Author
1741///
1742/// Hu Haixing
1743pub trait BinaryOperator<T>: BiTransformer<T, T, T> {}
1744
1745/// Blanket implementation of BinaryOperator for all BiTransformer<T, T, T>
1746///
1747/// This automatically implements `BinaryOperator<T>` for any type that
1748/// implements `BiTransformer<T, T, T>`.
1749///
1750/// # Author
1751///
1752/// Hu Haixing
1753impl<F, T> BinaryOperator<T> for F
1754where
1755    F: BiTransformer<T, T, T>,
1756    T: 'static,
1757{
1758    // empty
1759}
1760
1761// ============================================================================
1762// Type Aliases for BinaryOperator (BiTransformer<T, T, T>)
1763// ============================================================================
1764
1765/// Type alias for `BoxBiTransformer<T, T, T>`
1766///
1767/// Represents a binary operator that takes two values of type `T` and produces
1768/// a value of the same type `T`, with single ownership semantics. Equivalent to
1769/// Java's `BinaryOperator<T>`.
1770///
1771/// # Examples
1772///
1773/// ```rust
1774/// use prism3_function::{BoxBinaryOperator, BiTransformer};
1775///
1776/// let add: BoxBinaryOperator<i32> = BoxBinaryOperator::new(|x, y| x + y);
1777/// assert_eq!(add.apply(20, 22), 42);
1778/// ```
1779///
1780/// # Author
1781///
1782/// Hu Haixing
1783pub type BoxBinaryOperator<T> = BoxBiTransformer<T, T, T>;
1784
1785/// Type alias for `ArcBiTransformer<T, T, T>`
1786///
1787/// Represents a thread-safe binary operator that takes two values of type `T`
1788/// and produces a value of the same type `T`. Equivalent to Java's
1789/// `BinaryOperator<T>` with shared, thread-safe ownership.
1790///
1791/// # Examples
1792///
1793/// ```rust
1794/// use prism3_function::{ArcBinaryOperator, BiTransformer};
1795///
1796/// let multiply: ArcBinaryOperator<i32> = ArcBinaryOperator::new(|x, y| x * y);
1797/// let multiply_clone = multiply.clone();
1798/// assert_eq!(multiply.apply(6, 7), 42);
1799/// assert_eq!(multiply_clone.apply(6, 7), 42);
1800/// ```
1801///
1802/// # Author
1803///
1804/// Hu Haixing
1805pub type ArcBinaryOperator<T> = ArcBiTransformer<T, T, T>;
1806
1807/// Type alias for `RcBiTransformer<T, T, T>`
1808///
1809/// Represents a single-threaded binary operator that takes two values of type
1810/// `T` and produces a value of the same type `T`. Equivalent to Java's
1811/// `BinaryOperator<T>` with shared, single-threaded ownership.
1812///
1813/// # Examples
1814///
1815/// ```rust
1816/// use prism3_function::{RcBinaryOperator, BiTransformer};
1817///
1818/// let max: RcBinaryOperator<i32> = RcBinaryOperator::new(|x, y| if x > y { x } else { y });
1819/// let max_clone = max.clone();
1820/// assert_eq!(max.apply(30, 42), 42);
1821/// assert_eq!(max_clone.apply(30, 42), 42);
1822/// ```
1823///
1824/// # Author
1825///
1826/// Hu Haixing
1827pub type RcBinaryOperator<T> = RcBiTransformer<T, T, T>;