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