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