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>);