Skip to main content

qubit_function/transformers/
bi_transformer.rs

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