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 bi-transformer to a mutable closure (`FnMut`) with an explicit
180 /// method name.
181 ///
182 /// This is a naming alias of [`StatefulBiTransformer::into_fn`] to avoid
183 /// confusion with non-stateful `into_fn` methods that typically return `Fn`.
184 fn into_mut_fn(self) -> impl FnMut(T, U) -> R
185 where
186 Self: Sized + 'static,
187 {
188 self.into_fn()
189 }
190
191 /// Converts to BoxBiTransformerOnce
192 ///
193 /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
194 /// after calling this method.
195 ///
196 /// # Default Implementation
197 ///
198 /// The default implementation wraps `self` in a `Box` and creates a
199 /// `BoxBiTransformerOnce`. Types can override this method to provide more
200 /// efficient conversions.
201 ///
202 /// # Returns
203 ///
204 /// Returns `BoxBiTransformerOnce<T, U, R>`
205 fn into_once(self) -> BoxBiTransformerOnce<T, U, R>
206 where
207 Self: Sized + '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 {
220 self.clone().into_box()
221 }
222
223 /// Non-consuming conversion to `RcStatefulBiTransformer` using `&self`.
224 ///
225 /// Default implementation clones `self` and delegates to `into_rc`.
226 fn to_rc(&self) -> RcStatefulBiTransformer<T, U, R>
227 where
228 Self: Sized + Clone + 'static,
229 {
230 self.clone().into_rc()
231 }
232
233 /// Non-consuming conversion to `ArcStatefulBiTransformer` using `&self`.
234 ///
235 /// Default implementation clones `self` and delegates to `into_arc`.
236 fn to_arc(&self) -> ArcStatefulBiTransformer<T, U, R>
237 where
238 Self: Sized + Clone + Send + 'static,
239 {
240 self.clone().into_arc()
241 }
242
243 /// Non-consuming conversion to a boxed function using `&self`.
244 ///
245 /// Returns a `Box<dyn FnMut(T, U) -> R>` that clones `self` and calls
246 /// `apply` inside the boxed closure.
247 fn to_fn(&self) -> impl FnMut(T, U) -> R
248 where
249 Self: Sized + Clone + 'static,
250 {
251 self.clone().into_fn()
252 }
253
254 /// Non-consuming conversion to a mutable closure (`FnMut`) with an explicit
255 /// method name.
256 ///
257 /// This is a naming alias of [`StatefulBiTransformer::to_fn`] and keeps the
258 /// same clone-based behavior.
259 fn to_mut_fn(&self) -> impl FnMut(T, U) -> R
260 where
261 Self: Sized + Clone + 'static,
262 {
263 self.to_fn()
264 }
265
266 /// Non-consuming conversion to `BoxBiTransformerOnce` using `&self`.
267 ///
268 /// Default implementation clones `self` and delegates to `into_once`.
269 fn to_once(&self) -> BoxBiTransformerOnce<T, U, R>
270 where
271 Self: Sized + Clone + '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 // Zero-cost: directly return itself
330 self
331 }
332
333 fn into_rc(self) -> RcStatefulBiTransformer<T, U, R>
334 where
335 Self: 'static,
336 {
337 RcStatefulBiTransformer::new(self.function)
338 }
339
340 // do NOT override BoxStatefulBiTransformer::into_arc() because BoxStatefulBiTransformer is not Send + Sync
341 // and calling BoxStatefulBiTransformer::into_arc() will cause a compile error
342
343 fn into_fn(self) -> impl FnMut(T, U) -> R {
344 self.function
345 }
346
347 // do NOT override BoxStatefulBiTransformer::to_xxx() because BoxStatefulBiTransformer is not Clone
348 // and calling BoxStatefulBiTransformer::to_xxx() will cause a compile error
349}
350
351// ============================================================================
352// RcStatefulBiTransformer - Rc<dyn FnMut(T, U) -> R>
353// ============================================================================
354
355/// RcStatefulBiTransformer - single-threaded bi-transformer wrapper
356///
357/// A single-threaded, clonable bi-transformer wrapper optimized for scenarios
358/// that require sharing without thread-safety overhead.
359///
360/// # Features
361///
362/// - **Based on**: `Rc<dyn FnMut(T, U) -> R>`
363/// - **Ownership**: Shared ownership via reference counting (non-atomic)
364/// - **Reusability**: Can be called multiple times (each call consumes its
365/// inputs)
366/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
367/// - **Clonable**: Cheap cloning via `Rc::clone`
368///
369/// # Author
370///
371/// Haixing Hu
372pub struct RcStatefulBiTransformer<T, U, R> {
373 function: Rc<RefCell<dyn FnMut(T, U) -> R>>,
374 name: Option<String>,
375}
376
377impl<T, U, R> RcStatefulBiTransformer<T, U, R> {
378 impl_transformer_common_methods!(
379 RcStatefulBiTransformer<T, U, R>,
380 (FnMut(T, U) -> R + 'static),
381 |f| Rc::new(RefCell::new(f))
382 );
383
384 impl_shared_transformer_methods!(
385 RcStatefulBiTransformer<T, U, R>,
386 RcConditionalStatefulBiTransformer,
387 into_rc,
388 StatefulTransformer,
389 'static
390 );
391}
392
393// Implement constant method for RcStatefulBiTransformer
394impl_transformer_constant_method!(stateful RcStatefulBiTransformer<T, U, R>);
395
396// Implement Debug and Display for RcStatefulBiTransformer
397impl_transformer_debug_display!(RcStatefulBiTransformer<T, U, R>);
398
399// Implement Clone for RcStatefulBiTransformer
400impl_transformer_clone!(RcStatefulBiTransformer<T, U, R>);
401
402// Implement StatefulBiTransformer trait for RcStatefulBiTransformer
403impl<T, U, R> StatefulBiTransformer<T, U, R> for RcStatefulBiTransformer<T, U, R> {
404 fn apply(&mut self, first: T, second: U) -> R {
405 let mut self_fn = self.function.borrow_mut();
406 self_fn(first, second)
407 }
408
409 // Generate all conversion methods using the unified macro
410 impl_rc_conversions!(
411 RcStatefulBiTransformer<T, U, R>,
412 BoxStatefulBiTransformer,
413 BoxBiTransformerOnce,
414 FnMut(first: T, second: U) -> R
415 );
416}
417
418// ============================================================================
419// ArcStatefulBiTransformer - Arc<dyn FnMut(T, U) -> R + Send + Sync>
420// ============================================================================
421
422/// ArcStatefulBiTransformer - thread-safe bi-transformer wrapper
423///
424/// A thread-safe, clonable bi-transformer wrapper suitable for multi-threaded
425/// scenarios. Can be called multiple times and shared across threads.
426///
427/// # Features
428///
429/// - **Based on**: `Arc<dyn FnMut(T, U) -> R + Send + Sync>`
430/// - **Ownership**: Shared ownership via reference counting
431/// - **Reusability**: Can be called multiple times (each call consumes its
432/// inputs)
433/// - **Thread Safety**: Thread-safe (`Send + Sync` required)
434/// - **Clonable**: Cheap cloning via `Arc::clone`
435///
436/// # Author
437///
438/// Haixing Hu
439pub struct ArcStatefulBiTransformer<T, U, R> {
440 function: Arc<Mutex<dyn FnMut(T, U) -> R + Send>>,
441 name: Option<String>,
442}
443
444impl<T, U, R> ArcStatefulBiTransformer<T, U, R> {
445 impl_transformer_common_methods!(
446 ArcStatefulBiTransformer<T, U, R>,
447 (FnMut(T, U) -> R + Send + 'static),
448 |f| Arc::new(Mutex::new(f))
449 );
450
451 impl_shared_transformer_methods!(
452 ArcStatefulBiTransformer<T, U, R>,
453 ArcConditionalStatefulBiTransformer,
454 into_arc,
455 StatefulTransformer,
456 Send + Sync + 'static
457 );
458}
459
460// Implement constant method for ArcStatefulBiTransformer
461impl_transformer_constant_method!(stateful thread_safe ArcStatefulBiTransformer<T, U, R>);
462
463// Implement Debug and Display for ArcStatefulBiTransformer
464impl_transformer_debug_display!(ArcStatefulBiTransformer<T, U, R>);
465
466// Implement Clone for ArcStatefulBiTransformer
467impl_transformer_clone!(ArcStatefulBiTransformer<T, U, R>);
468
469// Implement StatefulBiTransformer trait for ArcStatefulBiTransformer
470impl<T, U, R> StatefulBiTransformer<T, U, R> for ArcStatefulBiTransformer<T, U, R> {
471 fn apply(&mut self, first: T, second: U) -> R {
472 let mut func = self.function.lock();
473 func(first, second)
474 }
475
476 // Use macro to implement conversion methods
477 impl_arc_conversions!(
478 ArcStatefulBiTransformer<T, U, R>,
479 BoxStatefulBiTransformer,
480 RcStatefulBiTransformer,
481 BoxBiTransformerOnce,
482 FnMut(t: T, u: U) -> R
483 );
484}
485
486// ============================================================================
487// Blanket implementation for standard Fn trait
488// ============================================================================
489
490// Implement StatefulBiTransformer<T, U, R> for any type that implements FnMut(T, U) -> R
491impl_closure_trait!(
492 StatefulBiTransformer<T, U, R>,
493 apply,
494 BoxBiTransformerOnce,
495 FnMut(first: T, second: U) -> R
496);
497
498// ============================================================================
499// FnStatefulBiTransformerOps - Extension trait for FnMut(T, U) -> R bi-transformers
500// ============================================================================
501
502/// Extension trait for closures implementing `FnMut(T, U) -> R`
503///
504/// Provides composition methods (`and_then`, `when`) for bi-transformer
505/// closures and function pointers without requiring explicit wrapping in
506/// `BoxStatefulBiTransformer`.
507///
508/// This trait is automatically implemented for all closures and function
509/// pointers that implement `FnMut(T, U) -> R`.
510///
511/// # Design Rationale
512///
513/// While closures automatically implement `StatefulBiTransformer<T, U, R>` through
514/// blanket implementation, they don't have access to instance methods like
515/// `and_then` and `when`. This extension trait provides those methods,
516/// returning `BoxStatefulBiTransformer` for maximum flexibility.
517///
518/// # Examples
519///
520/// ## Chain composition with and_then
521///
522/// ```rust
523/// use std::cell::Cell;
524/// use qubit_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
525///
526/// let add = |x: i32, y: i32| x + y;
527/// let double = |x: i32| x * 2;
528///
529/// let mut composed = add.and_then(double);
530/// assert_eq!(composed.apply(3, 5), 16); // (3 + 5) * 2
531/// ```
532///
533/// ## Conditional execution with when
534///
535/// ```rust
536/// use std::cell::Cell;
537/// use qubit_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
538///
539/// let add = |x: i32, y: i32| x + y;
540/// let multiply = |x: i32, y: i32| x * y;
541///
542/// let mut conditional = add.when(|x: &i32, y: &i32| *x > 0 && *y > 0).or_else(multiply);
543///
544/// assert_eq!(conditional.apply(5, 3), 8); // add
545/// assert_eq!(conditional.apply(-5, 3), -15); // multiply
546/// ```
547///
548/// # Author
549///
550/// Haixing Hu
551pub trait FnStatefulBiTransformerOps<T, U, R>: FnMut(T, U) -> R + Sized {
552 /// Chain composition - applies self first, then after
553 ///
554 /// Creates a new bi-transformer that applies this bi-transformer first,
555 /// then applies the after transformer to the result. Consumes self and
556 /// returns a `BoxStatefulBiTransformer`.
557 ///
558 /// # Type Parameters
559 ///
560 /// * `S` - The output type of the after transformer
561 /// * `F` - The type of the after transformer (must implement Transformer<R, S>)
562 ///
563 /// # Parameters
564 ///
565 /// * `after` - The transformer to apply after self. **Note: This parameter
566 /// is passed by value and will transfer ownership.** If you need to
567 /// preserve the original transformer, clone it first (if it implements
568 /// `Clone`). Can be:
569 /// - A closure: `|x: R| -> S`
570 /// - A function pointer: `fn(R) -> S`
571 /// - A `BoxTransformer<R, S>`
572 /// - An `RcTransformer<R, S>`
573 /// - An `ArcTransformer<R, S>`
574 /// - Any type implementing `Transformer<R, S>`
575 ///
576 /// # Returns
577 ///
578 /// A new `BoxStatefulBiTransformer<T, U, S>` representing the composition
579 ///
580 /// # Examples
581 ///
582 /// ## Direct value passing (ownership transfer)
583 ///
584 /// ```rust
585 /// use qubit_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
586 ///
587 /// let add = |x: i32, y: i32| x + y;
588 /// let to_string = |x: i32| x.to_string();
589 ///
590 /// // to_string is moved here
591 /// let mut composed = add.and_then(to_string);
592 /// assert_eq!(composed.apply(20, 22), "42");
593 /// // to_string(10); // Would not compile - moved
594 /// ```
595 ///
596 /// ## Preserving original with clone
597 ///
598 /// ```rust
599 /// use qubit_function::{StatefulBiTransformer, FnStatefulBiTransformerOps,
600 /// BoxTransformer};
601 ///
602 /// let add = |x: i32, y: i32| x + y;
603 /// let to_string = |x: i32| x.to_string();
604 ///
605 /// // Clone to preserve original
606 /// let mut composed = add.and_then(to_string.clone());
607 /// assert_eq!(composed.apply(20, 22), "42");
608 ///
609 /// // Original still usable
610 /// assert_eq!(to_string(10), "10");
611 /// ```
612 fn and_then<S, F>(self, after: F) -> BoxStatefulBiTransformer<T, U, S>
613 where
614 Self: 'static,
615 S: 'static,
616 F: StatefulTransformer<R, S> + 'static,
617 T: 'static,
618 U: 'static,
619 R: 'static,
620 {
621 BoxStatefulBiTransformer::new(self).and_then(after)
622 }
623
624 /// Creates a conditional bi-transformer
625 ///
626 /// Returns a bi-transformer that only executes when a bi-predicate is
627 /// satisfied. You must call `or_else()` to provide an alternative
628 /// bi-transformer for when the condition is not satisfied.
629 ///
630 /// # Parameters
631 ///
632 /// * `predicate` - The condition to check. **Note: This parameter is passed
633 /// by value and will transfer ownership.** If you need to preserve the
634 /// original bi-predicate, clone it first (if it implements `Clone`).
635 /// Can be:
636 /// - A closure: `|x: &T, y: &U| -> bool`
637 /// - A function pointer: `fn(&T, &U) -> bool`
638 /// - A `BoxBiPredicate<T, U>`
639 /// - An `RcBiPredicate<T, U>`
640 /// - An `ArcBiPredicate<T, U>`
641 /// - Any type implementing `BiPredicate<T, U>`
642 ///
643 /// # Returns
644 ///
645 /// Returns `BoxConditionalStatefulBiTransformer<T, U, R>`
646 ///
647 /// # Examples
648 ///
649 /// ## Basic usage with or_else
650 ///
651 /// ```rust
652 /// use std::cell::Cell;
653 /// use qubit_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
654 ///
655 /// let add = |x: i32, y: i32| x + y;
656 /// let mut conditional = add.when(|x: &i32, y: &i32| *x > 0)
657 /// .or_else(|x: i32, y: i32| x * y);
658 ///
659 /// assert_eq!(conditional.apply(5, 3), 8);
660 /// assert_eq!(conditional.apply(-5, 3), -15);
661 /// ```
662 ///
663 /// ## Preserving bi-predicate with clone
664 ///
665 /// ```rust
666 /// use qubit_function::{BiPredicate, StatefulBiTransformer, FnStatefulBiTransformerOps,
667 /// RcBiPredicate};
668 ///
669 /// let add = |x: i32, y: i32| x + y;
670 /// let both_positive = RcBiPredicate::new(|x: &i32, y: &i32|
671 /// *x > 0 && *y > 0);
672 ///
673 /// // Clone to preserve original bi-predicate
674 /// let mut conditional = add.when(both_positive.clone())
675 /// .or_else(|x: i32, y: i32| x * y);
676 ///
677 /// assert_eq!(conditional.apply(5, 3), 8);
678 ///
679 /// // Original bi-predicate still usable
680 /// assert!(both_positive.test(&5, &3));
681 /// ```
682 fn when<P>(self, predicate: P) -> BoxConditionalStatefulBiTransformer<T, U, R>
683 where
684 Self: 'static,
685 P: BiPredicate<T, U> + 'static,
686 T: 'static,
687 U: 'static,
688 R: 'static,
689 {
690 BoxStatefulBiTransformer::new(self).when(predicate)
691 }
692
693 /// Non-consuming conversion to a function using `&self`.
694 ///
695 /// Returns a closure that clones `self` and calls the bi-transformer.
696 /// This method requires that the bi-transformer implements `Clone`.
697 ///
698 /// # Type Parameters
699 ///
700 /// * `F` - The closure type (automatically inferred)
701 ///
702 /// # Returns
703 ///
704 /// Returns a closure that implements `FnMut(T, U) -> R`
705 ///
706 /// # Examples
707 ///
708 /// ```rust
709 /// use std::cell::Cell;
710 /// use qubit_function::{StatefulBiTransformer, FnStatefulBiTransformerOps};
711 ///
712 /// let counter = Cell::new(0);
713 /// let transformer = move |x: i32, y: i32| {
714 /// let c = counter.get() + 1;
715 /// counter.set(c);
716 /// x + y + c
717 /// };
718 ///
719 /// let mut fn_transformer = FnStatefulBiTransformerOps::to_fn(&transformer);
720 /// assert_eq!(fn_transformer(10, 20), 31);
721 /// assert_eq!(fn_transformer(10, 20), 32);
722 /// ```
723 fn to_fn(&self) -> impl FnMut(T, U) -> R
724 where
725 Self: Clone + 'static,
726 {
727 let mut cloned = self.clone();
728 move |t, u| cloned(t, u)
729 }
730}
731
732/// Blanket implementation of FnStatefulBiTransformerOps for all closures
733///
734/// Automatically implements `FnStatefulBiTransformerOps<T, U, R>` for any type that
735/// implements `FnMut(T, U) -> R`.
736///
737/// # Author
738///
739/// Haixing Hu
740impl<T, U, R, F> FnStatefulBiTransformerOps<T, U, R> for F where F: FnMut(T, U) -> R {}
741
742// ============================================================================
743// StatefulBinaryOperator Trait - Marker trait for StatefulBiTransformer<T, T, T>
744// ============================================================================
745
746/// StatefulBinaryOperator trait - marker trait for stateful binary operators
747///
748/// A binary operator takes two values of type `T` and produces a value of the
749/// same type `T`. This trait extends `StatefulBiTransformer<T, T, T>` to provide
750/// semantic clarity for same-type binary operations. Equivalent to Java's
751/// `BinaryOperator<T>` which extends `BiFunction<T, T, T>`.
752///
753/// # Automatic Implementation
754///
755/// This trait is automatically implemented for all types that implement
756/// `StatefulBiTransformer<T, T, T>`, so you don't need to implement it manually.
757///
758/// # Type Parameters
759///
760/// * `T` - The type of both input values and the output value
761///
762/// # Examples
763///
764/// ## Using in generic constraints
765///
766/// ```rust
767/// use qubit_function::{StatefulBinaryOperator, StatefulBiTransformer};
768///
769/// fn reduce<T, O>(values: Vec<T>, initial: T, mut op: O) -> T
770/// where
771/// O: StatefulBinaryOperator<T>,
772/// T: Clone,
773/// {
774/// values.into_iter().fold(initial, |acc, val| op.apply(acc, val))
775/// }
776///
777/// let sum = |a: i32, b: i32| a + b;
778/// assert_eq!(reduce(vec![1, 2, 3, 4], 0, sum), 10);
779/// ```
780///
781/// ## With concrete types
782///
783/// ```rust
784/// use qubit_function::{BoxStatefulBinaryOperator, StatefulBiTransformer};
785///
786/// fn create_adder() -> BoxStatefulBinaryOperator<i32> {
787/// BoxStatefulBinaryOperator::new(|x, y| x + y)
788/// }
789///
790/// let mut op = create_adder();
791/// assert_eq!(op.apply(20, 22), 42);
792/// ```
793///
794/// # Author
795///
796/// Haixing Hu
797pub trait StatefulBinaryOperator<T>: StatefulBiTransformer<T, T, T> {}
798
799/// Blanket implementation of StatefulBinaryOperator for all StatefulBiTransformer<T, T, T>
800///
801/// This automatically implements `StatefulBinaryOperator<T>` for any type that
802/// implements `StatefulBiTransformer<T, T, T>`.
803///
804/// # Author
805///
806/// Haixing Hu
807impl<F, T> StatefulBinaryOperator<T> for F
808where
809 F: StatefulBiTransformer<T, T, T>,
810{
811 // empty
812}
813
814// ============================================================================
815// Type Aliases for StatefulBinaryOperator (StatefulBiTransformer<T, T, T>)
816// ============================================================================
817
818/// Type alias for `BoxStatefulBiTransformer<T, T, T>`
819///
820/// Represents a binary operator that takes two values of type `T` and produces
821/// a value of the same type `T`, with single ownership semantics. Equivalent to
822/// Java's `BinaryOperator<T>`.
823///
824/// # Examples
825///
826/// ```rust
827/// use qubit_function::{BoxStatefulBinaryOperator, StatefulBiTransformer};
828///
829/// let add: BoxStatefulBinaryOperator<i32> = BoxStatefulBinaryOperator::new(|x, y| x + y);
830/// let mut add = add;
831/// assert_eq!(add.apply(20, 22), 42);
832/// ```
833///
834/// # Author
835///
836/// Haixing Hu
837pub type BoxStatefulBinaryOperator<T> = BoxStatefulBiTransformer<T, T, T>;
838
839/// Type alias for `ArcStatefulBiTransformer<T, T, T>`
840///
841/// Represents a thread-safe binary operator that takes two values of type `T`
842/// and produces a value of the same type `T`. Equivalent to Java's
843/// `BinaryOperator<T>` with shared, thread-safe ownership.
844///
845/// # Examples
846///
847/// ```rust
848/// use qubit_function::{ArcStatefulBinaryOperator, StatefulBiTransformer};
849///
850/// let multiply: ArcStatefulBinaryOperator<i32> = ArcStatefulBinaryOperator::new(|x, y| x * y);
851/// let mut multiply_clone = multiply.clone();
852/// let mut multiply = multiply;
853/// assert_eq!(multiply.apply(6, 7), 42);
854/// assert_eq!(multiply_clone.apply(6, 7), 42);
855/// ```
856///
857/// # Author
858///
859/// Haixing Hu
860pub type ArcStatefulBinaryOperator<T> = ArcStatefulBiTransformer<T, T, T>;
861
862/// Type alias for `RcStatefulBiTransformer<T, T, T>`
863///
864/// Represents a single-threaded binary operator that takes two values of type
865/// `T` and produces a value of the same type `T`. Equivalent to Java's
866/// `BinaryOperator<T>` with shared, single-threaded ownership.
867///
868/// # Examples
869///
870/// ```rust
871/// use qubit_function::{RcStatefulBinaryOperator, StatefulBiTransformer};
872///
873/// let max: RcStatefulBinaryOperator<i32> = RcStatefulBinaryOperator::new(|x, y| if x > y { x } else { y });
874/// let mut max_clone = max.clone();
875/// let mut max = max;
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 RcStatefulBinaryOperator<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 mut 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 mut conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
966///
967/// let mut 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 mut conditional = add.when(|x: &i32, y: &i32| *x > 0).or_else(multiply);
1024///
1025/// let mut 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>);