Skip to main content

qubit_function/functions/
function.rs

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