qubit_function/transformers/stateful_transformer.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # StatefulTransformer Types
10//!
11//! Provides Rust implementations of stateful transformer traits for stateful value
12//! transformation. StatefulTransformers consume input values (taking ownership) and
13//! produce output values while allowing internal state modification. This is
14//! analogous to `FnMut(T) -> R` in Rust's standard library.
15//!
16//! This module provides the `StatefulTransformer<T, R>` trait and three implementations:
17//!
18//! - [`BoxStatefulTransformer`]: Single ownership, not cloneable
19//! - [`ArcStatefulTransformer`]: Thread-safe shared ownership, cloneable
20//! - [`RcStatefulTransformer`]: 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_box_conversions,
34 impl_closure_trait,
35 impl_rc_conversions,
36};
37use crate::predicates::predicate::{
38 ArcPredicate,
39 BoxPredicate,
40 Predicate,
41 RcPredicate,
42};
43use crate::transformers::{
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 transformer_once::BoxTransformerOnce,
57};
58
59// ============================================================================
60// Core Trait
61// ============================================================================
62
63/// StatefulTransformer trait - transforms values from type T to type R with state
64///
65/// Defines the behavior of a stateful transformation: converting a value
66/// of type `T` to a value of type `R` by consuming the input while
67/// allowing modification of internal state. This is analogous to
68/// `FnMut(T) -> R` in Rust's standard library.
69///
70/// # Type Parameters
71///
72/// * `T` - The type of the input value (consumed)
73/// * `R` - The type of the output value
74///
75/// # Author
76///
77/// Haixing Hu
78pub trait StatefulTransformer<T, R> {
79 /// Applies the transformation to the input value to produce an output value
80 ///
81 /// # Parameters
82 ///
83 /// * `input` - The input value to transform (consumed)
84 ///
85 /// # Returns
86 ///
87 /// The transformed output value
88 fn apply(&mut self, input: T) -> R;
89
90 /// Converts to BoxStatefulTransformer
91 ///
92 /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
93 /// after calling this method.
94 ///
95 /// # Returns
96 ///
97 /// Returns `BoxStatefulTransformer<T, R>`
98 ///
99 /// # Default Implementation
100 ///
101 /// The default implementation wraps `self` in a `BoxStatefulTransformer` by creating
102 /// a new closure that calls `self.apply()`. This provides a zero-cost
103 /// abstraction for most use cases.
104 ///
105 /// # Examples
106 ///
107 /// ```rust
108 /// use qubit_function::{StatefulTransformer, BoxStatefulTransformer};
109 ///
110 /// struct CustomTransformer {
111 /// multiplier: i32,
112 /// }
113 ///
114 /// impl StatefulTransformer<i32, i32> for CustomTransformer {
115 /// fn apply(&mut self, input: i32) -> i32 {
116 /// self.multiplier += 1;
117 /// input * self.multiplier
118 /// }
119 /// }
120 ///
121 /// let transformer = CustomTransformer { multiplier: 0 };
122 /// let mut boxed = transformer.into_box();
123 /// assert_eq!(boxed.apply(10), 10); // 10 * 1
124 /// assert_eq!(boxed.apply(10), 20); // 10 * 2
125 /// ```
126 fn into_box(self) -> BoxStatefulTransformer<T, R>
127 where
128 Self: Sized + 'static,
129 T: 'static,
130 R: 'static,
131 {
132 let mut transformer = self;
133 BoxStatefulTransformer::new(move |t| transformer.apply(t))
134 }
135
136 /// Converts to RcStatefulTransformer
137 ///
138 /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
139 /// after calling this method.
140 ///
141 /// # Returns
142 ///
143 /// Returns `RcStatefulTransformer<T, R>`
144 ///
145 /// # Default Implementation
146 ///
147 /// The default implementation first converts to `BoxStatefulTransformer` using
148 /// `into_box()`, then wraps it in `RcStatefulTransformer`. Specific implementations
149 /// may override this for better efficiency.
150 ///
151 /// # Examples
152 ///
153 /// ```rust
154 /// use qubit_function::{StatefulTransformer, RcStatefulTransformer};
155 ///
156 /// struct CustomTransformer {
157 /// multiplier: i32,
158 /// }
159 ///
160 /// impl StatefulTransformer<i32, i32> for CustomTransformer {
161 /// fn apply(&mut self, input: i32) -> i32 {
162 /// self.multiplier += 1;
163 /// input * self.multiplier
164 /// }
165 /// }
166 ///
167 /// let transformer = CustomTransformer { multiplier: 0 };
168 /// let mut rc_transformer = transformer.into_rc();
169 /// assert_eq!(rc_transformer.apply(10), 10); // 10 * 1
170 /// assert_eq!(rc_transformer.apply(10), 20); // 10 * 2
171 /// ```
172 fn into_rc(self) -> RcStatefulTransformer<T, R>
173 where
174 Self: Sized + 'static,
175 T: 'static,
176 R: 'static,
177 {
178 let mut transformer = self;
179 RcStatefulTransformer::new(move |t| transformer.apply(t))
180 }
181
182 /// Converts to ArcStatefulTransformer
183 ///
184 /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
185 /// after calling this method.
186 ///
187 /// # Returns
188 ///
189 /// Returns `ArcStatefulTransformer<T, R>`
190 ///
191 /// # Default Implementation
192 ///
193 /// The default implementation wraps `self` in an `ArcStatefulTransformer` by creating
194 /// a new closure that calls `self.apply()`. Note that this requires `self`
195 /// to implement `Send` due to Arc's thread-safety requirements.
196 ///
197 /// # Examples
198 ///
199 /// ```rust
200 /// use qubit_function::{StatefulTransformer, ArcStatefulTransformer};
201 ///
202 /// struct CustomTransformer {
203 /// multiplier: i32,
204 /// }
205 ///
206 /// impl StatefulTransformer<i32, i32> for CustomTransformer {
207 /// fn apply(&mut self, input: i32) -> i32 {
208 /// self.multiplier += 1;
209 /// input * self.multiplier
210 /// }
211 /// }
212 ///
213 /// let transformer = CustomTransformer { multiplier: 0 };
214 /// let mut arc_transformer = transformer.into_arc();
215 /// assert_eq!(arc_transformer.apply(10), 10); // 10 * 1
216 /// assert_eq!(arc_transformer.apply(10), 20); // 10 * 2
217 /// ```
218 fn into_arc(self) -> ArcStatefulTransformer<T, R>
219 where
220 Self: Sized + Send + 'static,
221 T: Send + Sync + 'static,
222 R: Send + 'static,
223 {
224 let mut transformer = self;
225 ArcStatefulTransformer::new(move |t| transformer.apply(t))
226 }
227
228 /// Converts to a closure implementing `FnMut(T) -> R`
229 ///
230 /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
231 /// after calling this method.
232 ///
233 /// # Returns
234 ///
235 /// Returns an implementation of `FnMut(T) -> R`
236 ///
237 /// # Default Implementation
238 ///
239 /// The default implementation creates a new closure that calls `self.apply()`.
240 /// Specific implementations may override this for better efficiency.
241 ///
242 /// # Examples
243 ///
244 /// ```rust
245 /// use qubit_function::{StatefulTransformer, BoxStatefulTransformer};
246 ///
247 /// let transformer = BoxStatefulTransformer::new(|x: i32| x * 2);
248 /// let mut closure = transformer.into_fn();
249 /// assert_eq!(closure(10), 20);
250 /// assert_eq!(closure(15), 30);
251 /// ```
252 fn into_fn(self) -> impl FnMut(T) -> R
253 where
254 Self: Sized + 'static,
255 {
256 let mut transformer = self;
257 move |t| transformer.apply(t)
258 }
259
260 /// Converts to `BoxTransformerOnce`.
261 ///
262 /// This method has a default implementation that wraps the
263 /// transformer in a `BoxTransformerOnce`. Custom implementations
264 /// can override this method for optimization purposes.
265 ///
266 /// # Returns
267 ///
268 /// A new `BoxTransformerOnce<T, R>` instance
269 ///
270 /// # Examples
271 ///
272 /// ```rust
273 /// use qubit_function::StatefulTransformer;
274 ///
275 /// let closure = |x: i32| x * 2;
276 /// let once = closure.into_once();
277 /// assert_eq!(once.apply(5), 10);
278 /// ```
279 fn into_once(self) -> BoxTransformerOnce<T, R>
280 where
281 Self: Sized + 'static,
282 T: 'static,
283 R: 'static,
284 {
285 let mut transformer = self;
286 BoxTransformerOnce::new(move |t| transformer.apply(t))
287 }
288
289 /// Non-consuming conversion to `BoxStatefulTransformer`.
290 ///
291 /// Default implementation requires `Self: Clone` and wraps a cloned
292 /// instance in a `RefCell` so the returned transformer can mutate state
293 /// across calls.
294 fn to_box(&self) -> BoxStatefulTransformer<T, R>
295 where
296 Self: Sized + Clone + 'static,
297 T: 'static,
298 R: 'static,
299 {
300 self.clone().into_box()
301 }
302
303 /// Non-consuming conversion to `RcStatefulTransformer`.
304 ///
305 /// Default implementation clones `self` into an `Rc<RefCell<_>>` so the
306 /// resulting transformer can be shared within a single thread.
307 fn to_rc(&self) -> RcStatefulTransformer<T, R>
308 where
309 Self: Sized + Clone + 'static,
310 T: 'static,
311 R: 'static,
312 {
313 self.clone().into_rc()
314 }
315
316 /// Non-consuming conversion to `ArcStatefulTransformer` (thread-safe).
317 ///
318 /// Default implementation requires `Self: Clone + Send + Sync` and wraps
319 /// the cloned instance in `Arc<Mutex<_>>` so it can be used across
320 /// threads.
321 fn to_arc(&self) -> ArcStatefulTransformer<T, R>
322 where
323 Self: Sized + Clone + Send + Sync + 'static,
324 T: Send + Sync + 'static,
325 R: Send + 'static,
326 {
327 self.clone().into_arc()
328 }
329
330 /// Non-consuming conversion to a closure (`FnMut(T) -> R`).
331 ///
332 /// Default implementation clones `self` into a `RefCell` and returns a
333 /// closure that calls `apply` on the interior mutable value.
334 fn to_fn(&self) -> impl FnMut(T) -> R
335 where
336 Self: Sized + Clone + 'static,
337 {
338 self.clone().into_fn()
339 }
340
341 /// Creates a `BoxTransformerOnce` from a cloned transformer
342 ///
343 /// Uses `Clone` to obtain an owned copy and converts it into a
344 /// `BoxTransformerOnce`. Requires `Self: Clone`. Custom implementations
345 /// can override this for better performance.
346 fn to_once(&self) -> BoxTransformerOnce<T, R>
347 where
348 Self: Sized + Clone + 'static,
349 T: 'static,
350 R: 'static,
351 {
352 self.clone().into_once()
353 }
354}
355
356// ============================================================================
357// BoxStatefulTransformer - Box<dyn FnMut(T) -> R>
358// ============================================================================
359
360/// BoxStatefulTransformer - transformer wrapper based on `Box<dyn FnMut>`
361///
362/// A transformer wrapper that provides single ownership with reusable stateful
363/// transformation. The transformer consumes the input and can be called
364/// multiple times while maintaining internal state.
365///
366/// # Features
367///
368/// - **Based on**: `Box<dyn FnMut(T) -> R>`
369/// - **Ownership**: Single ownership, cannot be cloned
370/// - **Reusability**: Can be called multiple times (each call consumes
371/// its input)
372/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
373/// - **Statefulness**: Can modify internal state between calls
374///
375/// # Author
376///
377/// Haixing Hu
378pub struct BoxStatefulTransformer<T, R> {
379 function: Box<dyn FnMut(T) -> R>,
380 name: Option<String>,
381}
382
383impl<T, R> BoxStatefulTransformer<T, R> {
384 impl_transformer_common_methods!(
385 BoxStatefulTransformer<T, R>,
386 (FnMut(T) -> R + 'static),
387 |f| Box::new(f)
388 );
389
390 impl_box_transformer_methods!(
391 BoxStatefulTransformer<T, R>,
392 BoxConditionalStatefulTransformer,
393 StatefulTransformer
394 );
395}
396
397// Implement constant method for BoxStatefulTransformer
398impl_transformer_constant_method!(stateful BoxStatefulTransformer<T, R>);
399
400// Implement Debug and Display for BoxStatefulTransformer
401impl_transformer_debug_display!(BoxStatefulTransformer<T, R>);
402
403// Implement StatefulTransformer trait for BoxStatefulTransformer
404impl<T, R> StatefulTransformer<T, R> for BoxStatefulTransformer<T, R> {
405 fn apply(&mut self, input: T) -> R {
406 (self.function)(input)
407 }
408
409 // Generates: into_box(), into_rc(), into_fn(), into_once()
410 impl_box_conversions!(
411 BoxStatefulTransformer<T, R>,
412 RcStatefulTransformer,
413 FnMut(T) -> R,
414 BoxTransformerOnce
415 );
416
417 // do NOT override StatefulTransformer::to_xxx() because BoxStatefulTransformer is not Clone
418 // and calling BoxStatefulTransformer::to_xxx() will cause a compile error
419}
420
421// ============================================================================
422// RcStatefulTransformer - Rc<RefCell<dyn FnMut(T) -> R>>
423// ============================================================================
424
425/// RcStatefulTransformer - single-threaded transformer wrapper
426///
427/// A single-threaded, clonable transformer wrapper optimized for scenarios
428/// that require sharing without thread-safety overhead.
429///
430/// # Features
431///
432/// - **Based on**: `Rc<RefCell<dyn FnMut(T) -> R>>`
433/// - **Ownership**: Shared ownership via reference counting (non-atomic)
434/// - **Reusability**: Can be called multiple times (each call consumes
435/// its input)
436/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
437/// - **Clonable**: Cheap cloning via `Rc::clone`
438/// - **Statefulness**: Can modify internal state between calls
439///
440/// # Author
441///
442/// Haixing Hu
443pub struct RcStatefulTransformer<T, R> {
444 function: Rc<RefCell<dyn FnMut(T) -> R>>,
445 name: Option<String>,
446}
447
448// Implement RcStatefulTransformer
449impl<T, R> RcStatefulTransformer<T, R> {
450 impl_transformer_common_methods!(
451 RcStatefulTransformer<T, R>,
452 (FnMut(T) -> R + 'static),
453 |f| Rc::new(RefCell::new(f))
454 );
455
456 impl_shared_transformer_methods!(
457 RcStatefulTransformer<T, R>,
458 RcConditionalStatefulTransformer,
459 into_rc,
460 StatefulTransformer,
461 'static
462 );
463}
464
465// Implement constant method for RcStatefulTransformer
466impl_transformer_constant_method!(stateful RcStatefulTransformer<T, R>);
467
468// Implement Debug and Display for RcStatefulTransformer
469impl_transformer_debug_display!(RcStatefulTransformer<T, R>);
470
471// Implement Clone for RcStatefulTransformer
472impl_transformer_clone!(RcStatefulTransformer<T, R>);
473
474// Implement StatefulTransformer trait for RcStatefulTransformer
475impl<T, R> StatefulTransformer<T, R> for RcStatefulTransformer<T, R> {
476 fn apply(&mut self, input: T) -> R {
477 let mut self_fn = self.function.borrow_mut();
478 self_fn(input)
479 }
480
481 // Generate all conversion methods using the unified macro
482 impl_rc_conversions!(
483 RcStatefulTransformer<T, R>,
484 BoxStatefulTransformer,
485 BoxTransformerOnce,
486 FnMut(input: T) -> R
487 );
488}
489
490// ============================================================================
491// ArcStatefulTransformer - Arc<Mutex<dyn FnMut(T) -> R + Send>>
492// ============================================================================
493
494/// ArcStatefulTransformer - thread-safe transformer wrapper
495///
496/// A thread-safe, clonable transformer wrapper suitable for multi-threaded
497/// scenarios. Can be called multiple times and shared across threads
498/// while maintaining internal state.
499///
500/// # Features
501///
502/// - **Based on**: `Arc<Mutex<dyn FnMut(T) -> R + Send>>`
503/// - **Ownership**: Shared ownership via reference counting
504/// - **Reusability**: Can be called multiple times (each call consumes
505/// its input)
506/// - **Thread Safety**: Thread-safe (`Send` required)
507/// - **Clonable**: Cheap cloning via `Arc::clone`
508/// - **Statefulness**: Can modify internal state between calls
509///
510/// # Author
511///
512/// Haixing Hu
513pub struct ArcStatefulTransformer<T, R> {
514 function: Arc<Mutex<dyn FnMut(T) -> R + Send>>,
515 name: Option<String>,
516}
517
518impl<T, R> ArcStatefulTransformer<T, R> {
519 impl_transformer_common_methods!(
520 ArcStatefulTransformer<T, R>,
521 (FnMut(T) -> R + Send + 'static),
522 |f| Arc::new(Mutex::new(f))
523 );
524
525 impl_shared_transformer_methods!(
526 ArcStatefulTransformer<T, R>,
527 ArcConditionalStatefulTransformer,
528 into_arc,
529 StatefulTransformer,
530 Send + Sync + 'static
531 );
532}
533
534// Implement constant method for ArcStatefulTransformer
535impl_transformer_constant_method!(stateful thread_safe ArcStatefulTransformer<T, R>);
536
537// Implement Debug and Display for ArcStatefulTransformer
538impl_transformer_debug_display!(ArcStatefulTransformer<T, R>);
539
540// Implement Clone for ArcStatefulTransformer
541impl_transformer_clone!(ArcStatefulTransformer<T, R>);
542
543impl<T, R> StatefulTransformer<T, R> for ArcStatefulTransformer<T, R> {
544 fn apply(&mut self, input: T) -> R {
545 let mut func = self.function.lock();
546 func(input)
547 }
548
549 // Use macro to implement conversion methods
550 impl_arc_conversions!(
551 ArcStatefulTransformer<T, R>,
552 BoxStatefulTransformer,
553 RcStatefulTransformer,
554 BoxTransformerOnce,
555 FnMut(t: T) -> R
556 );
557}
558
559// ============================================================================
560// Blanket implementation for standard FnMut trait
561// ============================================================================
562
563// Implement StatefulTransformer<T, R> for any type that implements FnMut(T) -> R
564impl_closure_trait!(
565 StatefulTransformer<T, R>,
566 apply,
567 BoxTransformerOnce,
568 FnMut(input: T) -> R
569);
570
571// ============================================================================
572// FnStatefulTransformerOps - Extension trait for closure transformers
573// ============================================================================
574
575/// Extension trait for closures implementing `FnMut(T) -> R`
576///
577/// Provides composition methods (`and_then`, `compose`, `when`) for
578/// closures without requiring explicit wrapping in `BoxStatefulTransformer`,
579/// `RcStatefulTransformer`, or `ArcStatefulTransformer`.
580///
581/// This trait is automatically implemented for all closures that
582/// implement `FnMut(T) -> R`.
583///
584/// # Design Rationale
585///
586/// While closures automatically implement `StatefulTransformer<T, R>` through blanket
587/// implementation, they don't have access to instance methods like
588/// `and_then`, `compose`, and `when`. This extension trait provides
589/// those methods, returning `BoxStatefulTransformer` for maximum flexibility.
590///
591/// # Examples
592///
593/// ## Chain composition with and_then
594///
595/// ```rust
596/// use qubit_function::{StatefulTransformer, FnStatefulTransformerOps};
597///
598/// let mut counter1 = 0;
599/// let transformer1 = move |x: i32| {
600/// counter1 += 1;
601/// x + counter1
602/// };
603///
604/// let mut counter2 = 0;
605/// let transformer2 = move |x: i32| {
606/// counter2 += 1;
607/// x * counter2
608/// };
609///
610/// let mut composed = transformer1.and_then(transformer2);
611/// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
612/// ```
613///
614/// ## Reverse composition with compose
615///
616/// ```rust
617/// use qubit_function::{StatefulTransformer, FnStatefulTransformerOps};
618///
619/// let mut counter = 0;
620/// let transformer = move |x: i32| {
621/// counter += 1;
622/// x * counter
623/// };
624///
625/// let mut composed = transformer.compose(|x: i32| x + 1);
626/// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
627/// ```
628///
629/// ## Conditional mapping with when
630///
631/// ```rust
632/// use qubit_function::{StatefulTransformer, FnStatefulTransformerOps};
633///
634/// let mut transformer = (|x: i32| x * 2)
635/// .when(|x: &i32| *x > 0)
636/// .or_else(|x: i32| -x);
637///
638/// assert_eq!(transformer.apply(5), 10);
639/// assert_eq!(transformer.apply(-5), 5);
640/// ```
641///
642/// # Author
643///
644/// Haixing Hu
645pub trait FnStatefulTransformerOps<T, R>: FnMut(T) -> R + Sized {
646 /// Chain composition - applies self first, then after
647 ///
648 /// Creates a new transformer that applies this transformer first, then applies
649 /// the after transformer to the result. Consumes self and returns a
650 /// `BoxStatefulTransformer`.
651 ///
652 /// # Type Parameters
653 ///
654 /// * `S` - The output type of the after transformer
655 /// * `F` - The type of the after transformer (must implement StatefulTransformer<R, S>)
656 ///
657 /// # Parameters
658 ///
659 /// * `after` - The transformer to apply after self. Can be:
660 /// - A closure: `|x: R| -> S`
661 /// - A `BoxStatefulTransformer<R, S>`
662 /// - An `RcStatefulTransformer<R, S>`
663 /// - An `ArcStatefulTransformer<R, S>`
664 /// - Any type implementing `StatefulTransformer<R, S>`
665 ///
666 /// # Returns
667 ///
668 /// A new `BoxStatefulTransformer<T, S>` representing the composition
669 ///
670 /// # Examples
671 ///
672 /// ```rust
673 /// use qubit_function::{StatefulTransformer, FnStatefulTransformerOps, BoxStatefulTransformer};
674 ///
675 /// let mut counter1 = 0;
676 /// let transformer1 = move |x: i32| {
677 /// counter1 += 1;
678 /// x + counter1
679 /// };
680 ///
681 /// let mut counter2 = 0;
682 /// let transformer2 = BoxStatefulTransformer::new(move |x: i32| {
683 /// counter2 += 1;
684 /// x * counter2
685 /// });
686 ///
687 /// let mut composed = transformer1.and_then(transformer2);
688 /// assert_eq!(composed.apply(10), 11);
689 /// ```
690 fn and_then<S, F>(self, after: F) -> BoxStatefulTransformer<T, S>
691 where
692 Self: 'static,
693 S: 'static,
694 F: StatefulTransformer<R, S> + 'static,
695 T: 'static,
696 R: 'static,
697 {
698 BoxStatefulTransformer::new(self).and_then(after)
699 }
700
701 /// Creates a conditional transformer
702 ///
703 /// Returns a transformer that only executes when a predicate is satisfied.
704 /// You must call `or_else()` to provide an alternative transformer for
705 /// when the condition is not satisfied.
706 ///
707 /// # Parameters
708 ///
709 /// * `predicate` - The condition to check. Can be:
710 /// - A closure: `|x: &T| -> bool`
711 /// - A function pointer: `fn(&T) -> bool`
712 /// - A `BoxPredicate<T>`
713 /// - An `RcPredicate<T>`
714 /// - An `ArcPredicate<T>`
715 /// - Any type implementing `Predicate<T>`
716 ///
717 /// # Returns
718 ///
719 /// Returns `BoxConditionalStatefulTransformer<T, R>`
720 ///
721 /// # Examples
722 ///
723 /// ```rust
724 /// use qubit_function::{StatefulTransformer, FnStatefulTransformerOps};
725 ///
726 /// let mut transformer = (|x: i32| x * 2)
727 /// .when(|x: &i32| *x > 0)
728 /// .or_else(|x: i32| -x);
729 ///
730 /// assert_eq!(transformer.apply(5), 10);
731 /// assert_eq!(transformer.apply(-5), 5);
732 /// ```
733 fn when<P>(self, predicate: P) -> BoxConditionalStatefulTransformer<T, R>
734 where
735 Self: 'static,
736 P: Predicate<T> + 'static,
737 T: 'static,
738 R: 'static,
739 {
740 BoxStatefulTransformer::new(self).when(predicate)
741 }
742}
743
744/// Blanket implementation of FnStatefulTransformerOps for all closures
745///
746/// Automatically implements `FnStatefulTransformerOps<T, R>` for any type that
747/// implements `FnMut(T) -> R`.
748///
749/// # Author
750///
751/// Haixing Hu
752impl<T, R, F> FnStatefulTransformerOps<T, R> for F where F: FnMut(T) -> R {}
753
754// ============================================================================
755// BoxConditionalStatefulTransformer - Box-based Conditional StatefulTransformer
756// ============================================================================
757
758/// BoxConditionalStatefulTransformer struct
759///
760/// A conditional transformer that only executes when a predicate is satisfied.
761/// Uses `BoxStatefulTransformer` and `BoxPredicate` for single ownership semantics.
762///
763/// This type is typically created by calling `BoxStatefulTransformer::when()` and is
764/// designed to work with the `or_else()` method to create if-then-else
765/// logic.
766///
767/// # Features
768///
769/// - **Single Ownership**: Not cloneable, consumes `self` on use
770/// - **Conditional Execution**: Only maps when predicate returns `true`
771/// - **Chainable**: Can add `or_else` branch to create if-then-else
772/// logic
773/// - **Implements StatefulTransformer**: Can be used anywhere a `StatefulTransformer` is expected
774///
775/// # Examples
776///
777/// ```rust
778/// use qubit_function::{StatefulTransformer, BoxStatefulTransformer};
779///
780/// let mut high_count = 0;
781/// let mut low_count = 0;
782///
783/// let mut transformer = BoxStatefulTransformer::new(move |x: i32| {
784/// high_count += 1;
785/// x * 2
786/// })
787/// .when(|x: &i32| *x >= 10)
788/// .or_else(move |x| {
789/// low_count += 1;
790/// x + 1
791/// });
792///
793/// assert_eq!(transformer.apply(15), 30); // when branch executed
794/// assert_eq!(transformer.apply(5), 6); // or_else branch executed
795/// ```
796///
797/// # Author
798///
799/// Haixing Hu
800pub struct BoxConditionalStatefulTransformer<T, R> {
801 transformer: BoxStatefulTransformer<T, R>,
802 predicate: BoxPredicate<T>,
803}
804
805// Implement BoxConditionalTransformer
806impl_box_conditional_transformer!(
807 BoxConditionalStatefulTransformer<T, R>,
808 BoxStatefulTransformer,
809 StatefulTransformer
810);
811
812// Use macro to generate Debug and Display implementations
813impl_conditional_transformer_debug_display!(BoxConditionalStatefulTransformer<T, R>);
814
815// ============================================================================
816// RcConditionalStatefulTransformer - Rc-based Conditional StatefulTransformer
817// ============================================================================
818
819/// RcConditionalStatefulTransformer struct
820///
821/// A single-threaded conditional transformer that only executes when a
822/// predicate is satisfied. Uses `RcStatefulTransformer` and `RcPredicate` for shared
823/// ownership within a single thread.
824///
825/// This type is typically created by calling `RcStatefulTransformer::when()` and is
826/// designed to work with the `or_else()` method to create if-then-else
827/// logic.
828///
829/// # Features
830///
831/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
832/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
833/// - **Conditional Execution**: Only maps when predicate returns `true`
834/// - **No Lock Overhead**: More efficient than `ArcConditionalStatefulTransformer`
835///
836/// # Examples
837///
838/// ```rust
839/// use qubit_function::{StatefulTransformer, RcStatefulTransformer};
840///
841/// let mut transformer = RcStatefulTransformer::new(|x: i32| x * 2)
842/// .when(|x: &i32| *x > 0)
843/// .or_else(|x: i32| -x);
844///
845/// let mut transformer_clone = transformer.clone();
846///
847/// assert_eq!(transformer.apply(5), 10);
848/// assert_eq!(transformer_clone.apply(-5), 5);
849/// ```
850///
851/// # Author
852///
853/// Haixing Hu
854pub struct RcConditionalStatefulTransformer<T, R> {
855 transformer: RcStatefulTransformer<T, R>,
856 predicate: RcPredicate<T>,
857}
858
859// Implement RcConditionalStatefulTransformer
860impl_shared_conditional_transformer!(
861 RcConditionalStatefulTransformer<T, R>,
862 RcStatefulTransformer,
863 StatefulTransformer,
864 into_rc,
865 'static
866);
867
868// Use macro to generate Debug and Display implementations
869impl_conditional_transformer_debug_display!(RcConditionalStatefulTransformer<T, R>);
870
871// Implement Clone for RcConditionalStatefulTransformer
872impl_conditional_transformer_clone!(RcConditionalStatefulTransformer<T, R>);
873
874// ============================================================================
875// ArcConditionalStatefulTransformer - Arc-based Conditional StatefulTransformer
876// ============================================================================
877
878/// ArcConditionalStatefulTransformer struct
879///
880/// A thread-safe conditional transformer that only executes when a predicate
881/// is satisfied. Uses `ArcStatefulTransformer` and `ArcPredicate` for shared
882/// ownership across threads.
883///
884/// This type is typically created by calling `ArcStatefulTransformer::when()` and is
885/// designed to work with the `or_else()` method to create if-then-else
886/// logic.
887///
888/// # Features
889///
890/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
891/// - **Thread-Safe**: Implements `Send`, safe for concurrent use
892/// - **Conditional Execution**: Only maps when predicate returns `true`
893/// - **Chainable**: Can add `or_else` branch to create if-then-else
894/// logic
895///
896/// # Examples
897///
898/// ```rust
899/// use qubit_function::{StatefulTransformer, ArcStatefulTransformer};
900///
901/// let mut transformer = ArcStatefulTransformer::new(|x: i32| x * 2)
902/// .when(|x: &i32| *x > 0)
903/// .or_else(|x: i32| -x);
904///
905/// let mut transformer_clone = transformer.clone();
906///
907/// assert_eq!(transformer.apply(5), 10);
908/// assert_eq!(transformer_clone.apply(-5), 5);
909/// ```
910///
911/// # Author
912///
913/// Haixing Hu
914pub struct ArcConditionalStatefulTransformer<T, R> {
915 transformer: ArcStatefulTransformer<T, R>,
916 predicate: ArcPredicate<T>,
917}
918
919// Implement ArcConditionalStatefulTransformer
920impl_shared_conditional_transformer!(
921 ArcConditionalStatefulTransformer<T, R>,
922 ArcStatefulTransformer,
923 StatefulTransformer,
924 into_arc,
925 Send + Sync + 'static
926);
927
928// Use macro to generate Debug and Display implementations
929impl_conditional_transformer_debug_display!(ArcConditionalStatefulTransformer<T, R>);
930
931// Implement Clone for ArcConditionalStatefulTransformer
932impl_conditional_transformer_clone!(ArcConditionalStatefulTransformer<T, R>);