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