Skip to main content

qubit_function/functions/
function.rs

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