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