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
60mod box_function;
61pub use box_function::BoxFunction;
62mod rc_function;
63pub use rc_function::RcFunction;
64mod arc_function;
65pub use arc_function::ArcFunction;
66mod box_conditional_function;
67pub use box_conditional_function::BoxConditionalFunction;
68mod rc_conditional_function;
69pub use rc_conditional_function::RcConditionalFunction;
70mod arc_conditional_function;
71pub use arc_conditional_function::ArcConditionalFunction;
72mod fn_function_ops;
73pub use fn_function_ops::FnFunctionOps;
74
75// ============================================================================
76// Core Trait
77// ============================================================================
78
79/// Function trait - computes output from input reference
80///
81/// Defines the behavior of a function: computing a value of type `R`
82/// from a reference to type `T` without consuming the input. This is analogous to
83/// `Fn(&T) -> R` in Rust's standard library, similar to Java's `Function<T, R>`.
84///
85/// # Type Parameters
86///
87/// * `T` - The type of the input value (borrowed)
88/// * `R` - The type of the output value
89///
90/// # Author
91///
92/// Haixing Hu
93pub trait Function<T, R> {
94    /// Applies the function to the input reference to produce an output value
95    ///
96    /// # Parameters
97    ///
98    /// * `t` - Reference to the input value
99    ///
100    /// # Returns
101    ///
102    /// The computed output value
103    fn apply(&self, t: &T) -> R;
104
105    /// Converts to BoxFunction
106    ///
107    /// **⚠️ Consumes `self`**: The original function becomes
108    /// unavailable after calling this method.
109    ///
110    /// # Default Implementation
111    ///
112    /// The default implementation wraps `self` in a `Box` and creates a
113    /// `BoxFunction`. Types can override this method to provide more
114    /// efficient conversions.
115    ///
116    /// # Returns
117    ///
118    /// Returns `BoxFunction<T, R>`
119    fn into_box(self) -> BoxFunction<T, R>
120    where
121        Self: Sized + 'static,
122    {
123        BoxFunction::new(move |t| self.apply(t))
124    }
125
126    /// Converts to RcFunction
127    ///
128    /// **⚠️ Consumes `self`**: The original function becomes
129    /// unavailable after calling this method.
130    ///
131    /// # Default Implementation
132    ///
133    /// The default implementation wraps `self` in an `Rc` and creates an
134    /// `RcFunction`. Types can override this method to provide more
135    /// efficient conversions.
136    ///
137    /// # Returns
138    ///
139    /// Returns `RcFunction<T, R>`
140    fn into_rc(self) -> RcFunction<T, R>
141    where
142        Self: Sized + 'static,
143    {
144        RcFunction::new(move |t| self.apply(t))
145    }
146
147    /// Converts to ArcFunction
148    ///
149    /// **⚠️ Consumes `self`**: The original function becomes
150    /// unavailable after calling this method.
151    ///
152    /// # Default Implementation
153    ///
154    /// The default implementation wraps `self` in an `Arc` and creates
155    /// an `ArcFunction`. Types can override this method to provide
156    /// more efficient conversions.
157    ///
158    /// # Returns
159    ///
160    /// Returns `ArcFunction<T, R>`
161    fn into_arc(self) -> ArcFunction<T, R>
162    where
163        Self: Sized + Send + Sync + 'static,
164    {
165        ArcFunction::new(move |t| self.apply(t))
166    }
167
168    /// Converts function to a closure
169    ///
170    /// **⚠️ Consumes `self`**: The original function becomes
171    /// unavailable after calling this method.
172    ///
173    /// # Default Implementation
174    ///
175    /// The default implementation creates a closure that captures `self`
176    /// and calls its `transform` method. Types can override this method
177    /// to provide more efficient conversions.
178    ///
179    /// # Returns
180    ///
181    /// Returns a closure that implements `Fn(&T) -> R`
182    fn into_fn(self) -> impl Fn(&T) -> R
183    where
184        Self: Sized + 'static,
185    {
186        move |t| self.apply(t)
187    }
188
189    /// Converts to FunctionOnce
190    ///
191    /// **⚠️ Consumes `self`**: The original function becomes unavailable after calling this method.
192    ///
193    /// Converts a reusable function to a one-time function that consumes itself on use.
194    /// This enables passing `Function` to functions that require `FunctionOnce`.
195    ///
196    /// # Returns
197    ///
198    /// Returns a `BoxFunctionOnce<T, R>`
199    ///
200    /// # Examples
201    ///
202    /// ```rust
203    /// use qubit_function::{BoxFunction, Function, FunctionOnce};
204    ///
205    /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
206    ///     func.apply(value)
207    /// }
208    ///
209    /// let func = BoxFunction::new(|x: &i32| x * 2);
210    /// let result = takes_once(func.into_once(), &5);
211    /// assert_eq!(result, 10);
212    /// ```
213    fn into_once(self) -> BoxFunctionOnce<T, R>
214    where
215        Self: Sized + 'static,
216    {
217        BoxFunctionOnce::new(move |t| self.apply(t))
218    }
219
220    /// Converts to BoxFunction without consuming self
221    ///
222    /// **📌 Borrows `&self`**: The original function remains usable
223    /// after calling this method.
224    ///
225    /// # Default Implementation
226    ///
227    /// The default implementation creates a new `BoxFunction` that
228    /// captures a reference-counted clone. Types implementing `Clone`
229    /// can override this method to provide more efficient conversions.
230    ///
231    /// # Returns
232    ///
233    /// Returns `BoxFunction<T, R>`
234    ///
235    /// # Examples
236    ///
237    /// ```rust
238    /// use qubit_function::{ArcFunction, Function};
239    ///
240    /// let double = ArcFunction::new(|x: &i32| x * 2);
241    /// let boxed = double.to_box();
242    ///
243    /// // Original function still usable
244    /// assert_eq!(double.apply(&21), 42);
245    /// assert_eq!(boxed.apply(&21), 42);
246    /// ```
247    fn to_box(&self) -> BoxFunction<T, R>
248    where
249        Self: Clone + 'static,
250    {
251        self.clone().into_box()
252    }
253
254    /// Converts to RcFunction without consuming self
255    ///
256    /// **📌 Borrows `&self`**: The original function remains usable
257    /// after calling this method.
258    ///
259    /// # Default Implementation
260    ///
261    /// The default implementation creates a new `RcFunction` that
262    /// captures a reference-counted clone. Types implementing `Clone`
263    /// can override this method to provide more efficient conversions.
264    ///
265    /// # Returns
266    ///
267    /// Returns `RcFunction<T, R>`
268    ///
269    /// # Examples
270    ///
271    /// ```rust
272    /// use qubit_function::{RcFunction, Function};
273    ///
274    /// let double = RcFunction::new(|x: &i32| x * 2);
275    /// let rc = double.to_rc();
276    ///
277    /// // Original function still usable
278    /// assert_eq!(double.apply(&21), 42);
279    /// assert_eq!(rc.apply(&21), 42);
280    /// ```
281    fn to_rc(&self) -> RcFunction<T, R>
282    where
283        Self: Clone + 'static,
284    {
285        self.clone().into_rc()
286    }
287
288    /// Converts to ArcFunction without consuming self
289    ///
290    /// **📌 Borrows `&self`**: The original function remains usable
291    /// after calling this method.
292    ///
293    /// # Default Implementation
294    ///
295    /// The default implementation creates a new `ArcFunction` that
296    /// captures a reference-counted clone. Types implementing `Clone`
297    /// can override this method to provide more efficient conversions.
298    ///
299    /// # Returns
300    ///
301    /// Returns `ArcFunction<T, R>`
302    ///
303    /// # Examples
304    ///
305    /// ```rust
306    /// use qubit_function::{ArcFunction, Function};
307    ///
308    /// let double = ArcFunction::new(|x: &i32| x * 2);
309    /// let arc = double.to_arc();
310    ///
311    /// // Original function still usable
312    /// assert_eq!(double.apply(&21), 42);
313    /// assert_eq!(arc.apply(&21), 42);
314    /// ```
315    fn to_arc(&self) -> ArcFunction<T, R>
316    where
317        Self: Clone + Send + Sync + 'static,
318    {
319        self.clone().into_arc()
320    }
321
322    /// Converts function to a closure without consuming self
323    ///
324    /// **📌 Borrows `&self`**: The original function remains usable
325    /// after calling this method.
326    ///
327    /// # Default Implementation
328    ///
329    /// The default implementation creates a closure that captures a
330    /// clone of `self` and calls its `transform` method. Types can
331    /// override this method to provide more efficient conversions.
332    ///
333    /// # Returns
334    ///
335    /// Returns a closure that implements `Fn(&T) -> R`
336    ///
337    /// # Examples
338    ///
339    /// ```rust
340    /// use qubit_function::{ArcFunction, Function};
341    ///
342    /// let double = ArcFunction::new(|x: &i32| x * 2);
343    /// let closure = double.to_fn();
344    ///
345    /// // Original function still usable
346    /// assert_eq!(double.apply(&21), 42);
347    /// assert_eq!(closure(&21), 42);
348    /// ```
349    fn to_fn(&self) -> impl Fn(&T) -> R
350    where
351        Self: Clone + 'static,
352    {
353        self.clone().into_fn()
354    }
355
356    /// Convert to FunctionOnce without consuming self
357    ///
358    /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
359    /// Clones the current function and converts the clone to a one-time function.
360    ///
361    /// # Returns
362    ///
363    /// Returns a `BoxFunctionOnce<T, R>`
364    ///
365    /// # Examples
366    ///
367    /// ```rust
368    ///
369    /// use qubit_function::{Function, FunctionOnce, RcFunction};
370    ///
371    /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
372    ///     func.apply(value)
373    /// }
374    ///
375    /// let func = RcFunction::new(|x: &i32| x * 2);
376    /// let result = takes_once(func.to_once(), &5);
377    /// assert_eq!(result, 10);
378    /// ```
379    fn to_once(&self) -> BoxFunctionOnce<T, R>
380    where
381        Self: Clone + 'static,
382    {
383        self.clone().into_once()
384    }
385}