Skip to main content

qubit_function/transformers/
stateful_bi_transformer.rs

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