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