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    /// use qubit_function::{BoxFunction, Function, FunctionOnce};
189    ///
190    /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
191    ///     func.apply(value)
192    /// }
193    ///
194    /// let func = BoxFunction::new(|x: &i32| x * 2);
195    /// let result = takes_once(func.into_once(), &5);
196    /// assert_eq!(result, 10);
197    /// ```
198    fn into_once(self) -> BoxFunctionOnce<T, R>
199    where
200        Self: Sized + 'static,
201    {
202        BoxFunctionOnce::new(move |t| self.apply(t))
203    }
204
205    /// Converts to BoxFunction without consuming self
206    ///
207    /// **📌 Borrows `&self`**: The original function remains usable
208    /// after calling this method.
209    ///
210    /// # Default Implementation
211    ///
212    /// The default implementation creates a new `BoxFunction` that
213    /// captures a reference-counted clone. Types implementing `Clone`
214    /// can override this method to provide more efficient conversions.
215    ///
216    /// # Returns
217    ///
218    /// Returns `BoxFunction<T, R>`
219    ///
220    /// # Examples
221    ///
222    /// ```rust
223    /// use qubit_function::{ArcFunction, Function};
224    ///
225    /// let double = ArcFunction::new(|x: &i32| x * 2);
226    /// let boxed = double.to_box();
227    ///
228    /// // Original function still usable
229    /// assert_eq!(double.apply(&21), 42);
230    /// assert_eq!(boxed.apply(&21), 42);
231    /// ```
232    fn to_box(&self) -> BoxFunction<T, R>
233    where
234        Self: Clone + 'static,
235    {
236        self.clone().into_box()
237    }
238
239    /// Converts to RcFunction without consuming self
240    ///
241    /// **📌 Borrows `&self`**: The original function remains usable
242    /// after calling this method.
243    ///
244    /// # Default Implementation
245    ///
246    /// The default implementation creates a new `RcFunction` that
247    /// captures a reference-counted clone. Types implementing `Clone`
248    /// can override this method to provide more efficient conversions.
249    ///
250    /// # Returns
251    ///
252    /// Returns `RcFunction<T, R>`
253    ///
254    /// # Examples
255    ///
256    /// ```rust
257    /// use qubit_function::{RcFunction, Function};
258    ///
259    /// let double = RcFunction::new(|x: &i32| x * 2);
260    /// let rc = double.to_rc();
261    ///
262    /// // Original function still usable
263    /// assert_eq!(double.apply(&21), 42);
264    /// assert_eq!(rc.apply(&21), 42);
265    /// ```
266    fn to_rc(&self) -> RcFunction<T, R>
267    where
268        Self: Clone + 'static,
269    {
270        self.clone().into_rc()
271    }
272
273    /// Converts to ArcFunction without consuming self
274    ///
275    /// **📌 Borrows `&self`**: The original function remains usable
276    /// after calling this method.
277    ///
278    /// # Default Implementation
279    ///
280    /// The default implementation creates a new `ArcFunction` that
281    /// captures a reference-counted clone. Types implementing `Clone`
282    /// can override this method to provide more efficient conversions.
283    ///
284    /// # Returns
285    ///
286    /// Returns `ArcFunction<T, R>`
287    ///
288    /// # Examples
289    ///
290    /// ```rust
291    /// use qubit_function::{ArcFunction, Function};
292    ///
293    /// let double = ArcFunction::new(|x: &i32| x * 2);
294    /// let arc = double.to_arc();
295    ///
296    /// // Original function still usable
297    /// assert_eq!(double.apply(&21), 42);
298    /// assert_eq!(arc.apply(&21), 42);
299    /// ```
300    fn to_arc(&self) -> ArcFunction<T, R>
301    where
302        Self: Clone + Send + Sync + 'static,
303    {
304        self.clone().into_arc()
305    }
306
307    /// Converts function to a closure without consuming self
308    ///
309    /// **📌 Borrows `&self`**: The original function remains usable
310    /// after calling this method.
311    ///
312    /// # Default Implementation
313    ///
314    /// The default implementation creates a closure that captures a
315    /// clone of `self` and calls its `transform` method. Types can
316    /// override this method to provide more efficient conversions.
317    ///
318    /// # Returns
319    ///
320    /// Returns a closure that implements `Fn(&T) -> R`
321    ///
322    /// # Examples
323    ///
324    /// ```rust
325    /// use qubit_function::{ArcFunction, Function};
326    ///
327    /// let double = ArcFunction::new(|x: &i32| x * 2);
328    /// let closure = double.to_fn();
329    ///
330    /// // Original function still usable
331    /// assert_eq!(double.apply(&21), 42);
332    /// assert_eq!(closure(&21), 42);
333    /// ```
334    fn to_fn(&self) -> impl Fn(&T) -> R
335    where
336        Self: Clone + 'static,
337    {
338        self.clone().into_fn()
339    }
340
341    /// Convert to FunctionOnce without consuming self
342    ///
343    /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
344    /// Clones the current function and converts the clone to a one-time function.
345    ///
346    /// # Returns
347    ///
348    /// Returns a `BoxFunctionOnce<T, R>`
349    ///
350    /// # Examples
351    ///
352    /// ```rust
353    ///
354    /// use qubit_function::{Function, FunctionOnce, RcFunction};
355    ///
356    /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
357    ///     func.apply(value)
358    /// }
359    ///
360    /// let func = RcFunction::new(|x: &i32| x * 2);
361    /// let result = takes_once(func.to_once(), &5);
362    /// assert_eq!(result, 10);
363    /// ```
364    fn to_once(&self) -> BoxFunctionOnce<T, R>
365    where
366        Self: Clone + 'static,
367    {
368        self.clone().into_once()
369    }
370}
371
372// ============================================================================
373// BoxFunction - Box<dyn Fn(&T) -> R>
374// ============================================================================
375
376/// BoxFunction - function wrapper based on `Box<dyn Fn>`
377///
378/// A function wrapper that provides single ownership with reusable
379/// transformation. The function consumes the input and can be called
380/// multiple times.
381///
382/// # Features
383///
384/// - **Based on**: `Box<dyn Fn(&T) -> R>`
385/// - **Ownership**: Single ownership, cannot be cloned
386/// - **Reusability**: Can be called multiple times (each call consumes its
387///   input)
388/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
389///
390/// # Author
391///
392/// Haixing Hu
393pub struct BoxFunction<T, R> {
394    function: Box<dyn Fn(&T) -> R>,
395    name: Option<String>,
396}
397
398impl<T, R> BoxFunction<T, R> {
399    // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
400    impl_function_common_methods!(
401        BoxFunction<T, R>,
402        (Fn(&T) -> R + 'static),
403        |f| Box::new(f)
404    );
405
406    // Generates: when(), and_then(), compose()
407    impl_box_function_methods!(
408        BoxFunction<T, R>,
409        BoxConditionalFunction,
410        Function
411    );
412}
413
414// Generates: constant() method for BoxFunction<T, R>
415impl_function_constant_method!(BoxFunction<T, R>, 'static);
416
417// Generates: identity() method for BoxFunction<T, T>
418impl_function_identity_method!(BoxFunction<T, T>);
419
420// Generates: Debug and Display implementations for BoxFunction<T, R>
421impl_function_debug_display!(BoxFunction<T, R>);
422
423// Implement Function trait for BoxFunction<T, R>
424impl<T, R> Function<T, R> for BoxFunction<T, R> {
425    fn apply(&self, t: &T) -> R {
426        (self.function)(t)
427    }
428
429    // Generates: into_box(), into_rc(), into_fn(), into_once()
430    impl_box_conversions!(
431        BoxFunction<T, R>,
432        RcFunction,
433        Fn(&T) -> R,
434        BoxFunctionOnce
435    );
436}
437
438// ============================================================================
439// RcFunction - Rc<dyn Fn(&T) -> R>
440// ============================================================================
441
442/// RcFunction - single-threaded function wrapper
443///
444/// A single-threaded, clonable function wrapper optimized for scenarios
445/// that require sharing without thread-safety overhead.
446///
447/// # Features
448///
449/// - **Based on**: `Rc<dyn Fn(&T) -> R>`
450/// - **Ownership**: Shared ownership via reference counting (non-atomic)
451/// - **Reusability**: Can be called multiple times (each call consumes its
452///   input)
453/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
454/// - **Clonable**: Cheap cloning via `Rc::clone`
455///
456/// # Author
457///
458/// Haixing Hu
459pub struct RcFunction<T, R> {
460    function: Rc<dyn Fn(&T) -> R>,
461    name: Option<String>,
462}
463
464impl<T, R> RcFunction<T, R> {
465    // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
466    impl_function_common_methods!(
467        RcFunction<T, R>,
468        (Fn(&T) -> R + 'static),
469        |f| Rc::new(f)
470    );
471
472    // Generates: when(), and_then(), compose()
473    impl_shared_function_methods!(
474        RcFunction<T, R>,
475        RcConditionalFunction,
476        into_rc,
477        Function,
478        'static
479    );
480}
481
482// Generates: constant() method for RcFunction<T, R>
483impl_function_constant_method!(RcFunction<T, R>, 'static);
484
485// Generates: identity() method for RcFunction<T, T>
486impl_function_identity_method!(RcFunction<T, T>);
487
488// Generates: Clone implementation for RcFunction<T, R>
489impl_function_clone!(RcFunction<T, R>);
490
491// Generates: Debug and Display implementations for RcFunction<T, R>
492impl_function_debug_display!(RcFunction<T, R>);
493
494// Implement Function trait for RcFunction<T, R>
495impl<T, R> Function<T, R> for RcFunction<T, R> {
496    fn apply(&self, t: &T) -> R {
497        (self.function)(t)
498    }
499
500    // Use macro to implement conversion methods
501    impl_rc_conversions!(
502        RcFunction<T, R>,
503        BoxFunction,
504        BoxFunctionOnce,
505        Fn(t: &T) -> R
506    );
507}
508
509// ============================================================================
510// ArcFunction - Arc<dyn Fn(&T) -> R + Send + Sync>
511// ============================================================================
512
513/// ArcFunction - thread-safe function wrapper
514///
515/// A thread-safe, clonable function wrapper suitable for multi-threaded
516/// scenarios. Can be called multiple times and shared across threads.
517///
518/// # Features
519///
520/// - **Based on**: `Arc<dyn Fn(&T) -> R + Send + Sync>`
521/// - **Ownership**: Shared ownership via reference counting
522/// - **Reusability**: Can be called multiple times (each call consumes its
523///   input)
524/// - **Thread Safety**: Thread-safe (`Send + Sync` required)
525/// - **Clonable**: Cheap cloning via `Arc::clone`
526///
527/// # Author
528///
529/// Haixing Hu
530pub struct ArcFunction<T, R> {
531    function: Arc<dyn Fn(&T) -> R + Send + Sync>,
532    name: Option<String>,
533}
534
535impl<T, R> ArcFunction<T, R> {
536    // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
537    impl_function_common_methods!(
538        ArcFunction<T, R>,
539        (Fn(&T) -> R + Send + Sync + 'static),
540        |f| Arc::new(f)
541    );
542
543    // Generates: when(), and_then(), compose()
544    impl_shared_function_methods!(
545        ArcFunction<T, R>,
546        ArcConditionalFunction,
547        into_arc,
548        Function,
549        Send + Sync + 'static
550    );
551}
552
553// Generates: constant() method for ArcFunction<T, R>
554impl_function_constant_method!(ArcFunction<T, R>, Send + Sync + 'static);
555
556// Generates: identity() method for ArcFunction<T, T>
557impl_function_identity_method!(ArcFunction<T, T>);
558
559// Generates: Clone implementation for ArcFunction<T, R>
560impl_function_clone!(ArcFunction<T, R>);
561
562// Generates: Debug and Display implementations for ArcFunction<T, R>
563impl_function_debug_display!(ArcFunction<T, R>);
564
565// Implement Function trait for ArcFunction<T, R>
566impl<T, R> Function<T, R> for ArcFunction<T, R> {
567    fn apply(&self, t: &T) -> R {
568        (self.function)(t)
569    }
570
571    // Use macro to implement conversion methods
572    impl_arc_conversions!(
573        ArcFunction<T, R>,
574        BoxFunction,
575        RcFunction,
576        BoxFunctionOnce,
577        Fn(t: &T) -> R
578    );
579}
580
581// ============================================================================
582// Blanket implementation for standard Fn trait
583// ============================================================================
584
585// Implement Function<T, R> for any type that implements Fn(&T) -> R
586impl_closure_trait!(
587    Function<T, R>,
588    apply,
589    BoxFunctionOnce,
590    Fn(input: &T) -> R
591);
592
593// ============================================================================
594// FnFunctionOps - Extension trait for closure functions
595// ============================================================================
596
597// Generates: FnFunctionOps trait and blanket implementation
598impl_fn_ops_trait!(
599    (Fn(&T) -> R),
600    FnFunctionOps,
601    BoxFunction,
602    Function,
603    BoxConditionalFunction
604);
605
606// ============================================================================
607// BoxConditionalFunction - Box-based Conditional Function
608// ============================================================================
609
610/// BoxConditionalFunction struct
611///
612/// A conditional function that only executes when a predicate is satisfied.
613/// Uses `BoxFunction` and `BoxPredicate` for single ownership semantics.
614///
615/// This type is typically created by calling `BoxFunction::when()` and is
616/// designed to work with the `or_else()` method to create if-then-else logic.
617///
618/// # Features
619///
620/// - **Single Ownership**: Not cloneable, consumes `self` on use
621/// - **Conditional Execution**: Only transforms when predicate returns `true`
622/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
623/// - **Implements Function**: Can be used anywhere a `Function` is expected
624///
625/// # Examples
626///
627/// ## With or_else Branch
628///
629/// ```rust
630/// use qubit_function::{Function, BoxFunction};
631///
632/// let double = BoxFunction::new(|x: &i32| x * 2);
633/// let negate = BoxFunction::new(|x: &i32| -x);
634/// let conditional = double.when(|x: &i32| *x > 0).or_else(negate);
635///
636/// assert_eq!(conditional.apply(&5), 10); // when branch executed
637/// assert_eq!(conditional.apply(&-5), 5); // or_else branch executed
638/// ```
639///
640/// # Author
641///
642/// Haixing Hu
643pub struct BoxConditionalFunction<T, R> {
644    function: BoxFunction<T, R>,
645    predicate: BoxPredicate<T>,
646}
647
648// Use macro to generate conditional function implementations
649impl_box_conditional_function!(
650    BoxConditionalFunction<T, R>,
651    BoxFunction,
652    Function
653);
654
655// Use macro to generate conditional function debug and display implementations
656impl_conditional_function_debug_display!(BoxConditionalFunction<T, R>);
657
658// ============================================================================
659// RcConditionalFunction - Rc-based Conditional Function
660// ============================================================================
661
662/// RcConditionalFunction struct
663///
664/// A single-threaded conditional function that only executes when a
665/// predicate is satisfied. Uses `RcFunction` and `RcPredicate` for shared
666/// ownership within a single thread.
667///
668/// This type is typically created by calling `RcFunction::when()` and is
669/// designed to work with the `or_else()` method to create if-then-else logic.
670///
671/// # Features
672///
673/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
674/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
675/// - **Conditional Execution**: Only transforms when predicate returns `true`
676/// - **No Lock Overhead**: More efficient than `ArcConditionalFunction`
677///
678/// # Examples
679///
680/// ```rust
681/// use qubit_function::{Function, RcFunction};
682///
683/// let double = RcFunction::new(|x: &i32| x * 2);
684/// let identity = RcFunction::<i32, i32>::identity();
685/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
686///
687/// let conditional_clone = conditional.clone();
688///
689/// assert_eq!(conditional.apply(&5), 10);
690/// assert_eq!(conditional_clone.apply(&-5), -5);
691/// ```
692///
693/// # Author
694///
695/// Haixing Hu
696pub struct RcConditionalFunction<T, R> {
697    function: RcFunction<T, R>,
698    predicate: RcPredicate<T>,
699}
700
701// Use macro to generate conditional function implementations
702impl_shared_conditional_function!(
703    RcConditionalFunction<T, R>,
704    RcFunction,
705    Function,
706    'static
707);
708
709// Use macro to generate conditional function clone implementations
710impl_conditional_function_clone!(RcConditionalFunction<T, R>);
711
712// Use macro to generate conditional function debug and display implementations
713impl_conditional_function_debug_display!(RcConditionalFunction<T, R>);
714
715// ============================================================================
716// ArcConditionalFunction - Arc-based Conditional Function
717// ============================================================================
718
719/// ArcConditionalFunction struct
720///
721/// A thread-safe conditional function that only executes when a predicate is
722/// satisfied. Uses `ArcFunction` and `ArcPredicate` for shared ownership
723/// across threads.
724///
725/// This type is typically created by calling `ArcFunction::when()` and is
726/// designed to work with the `or_else()` method to create if-then-else logic.
727///
728/// # Features
729///
730/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
731/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
732/// - **Conditional Execution**: Only transforms when predicate returns `true`
733/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
734///
735/// # Examples
736///
737/// ```rust
738/// use qubit_function::{Function, ArcFunction};
739///
740/// let double = ArcFunction::new(|x: &i32| x * 2);
741/// let identity = ArcFunction::<i32, i32>::identity();
742/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
743///
744/// let conditional_clone = conditional.clone();
745///
746/// assert_eq!(conditional.apply(&5), 10);
747/// assert_eq!(conditional_clone.apply(&-5), -5);
748/// ```
749///
750/// # Author
751///
752/// Haixing Hu
753pub struct ArcConditionalFunction<T, R> {
754    function: ArcFunction<T, R>,
755    predicate: ArcPredicate<T>,
756}
757
758// Use macro to generate conditional function implementations
759impl_shared_conditional_function!(
760    ArcConditionalFunction<T, R>,
761    ArcFunction,
762    Function,
763    Send + Sync + 'static
764);
765
766// Use macro to generate conditional function clone implementations
767impl_conditional_function_clone!(ArcConditionalFunction<T, R>);
768
769// Use macro to generate conditional function debug and display implementations
770impl_conditional_function_debug_display!(ArcConditionalFunction<T, R>);