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