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