Skip to main content

qubit_function/functions/
function_once.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # FunctionOnce Types
10//!
11//! Provides Rust implementations of consuming function traits similar to
12//! Rust's `FnOnce(&T) -> R` trait, for computing output from input references.
13//!
14//! This module provides the `FunctionOnce<T, R>` trait and one-time use
15//! implementations:
16//!
17//! - [`BoxFunctionOnce`]: Single ownership, one-time use
18//!
19//! # Author
20//!
21//! Haixing Hu
22use crate::functions::macros::{
23    impl_box_conditional_function,
24    impl_box_function_methods,
25    impl_conditional_function_debug_display,
26    impl_fn_ops_trait,
27    impl_function_common_methods,
28    impl_function_constant_method,
29    impl_function_debug_display,
30    impl_function_identity_method,
31};
32use crate::macros::{
33    impl_box_once_conversions,
34    impl_closure_once_trait,
35};
36use crate::predicates::predicate::{
37    BoxPredicate,
38    Predicate,
39};
40
41mod box_function_once;
42pub use box_function_once::BoxFunctionOnce;
43mod box_conditional_function_once;
44pub use box_conditional_function_once::BoxConditionalFunctionOnce;
45mod fn_function_once_ops;
46pub use fn_function_once_ops::FnFunctionOnceOps;
47
48// ============================================================================
49// Core Trait
50// ============================================================================
51
52/// FunctionOnce trait - consuming function that takes ownership
53///
54/// Defines the behavior of a consuming function: computing a value of
55/// type `R` from a reference to type `T` by taking ownership of self.
56/// This trait is analogous to `FnOnce(&T) -> R`.
57///
58/// # Type Parameters
59///
60/// * `T` - The type of the input value (borrowed)
61/// * `R` - The type of the output value
62///
63/// # Author
64///
65/// Haixing Hu
66pub trait FunctionOnce<T, R> {
67    /// Applies the function to the input reference, consuming self
68    ///
69    /// # Parameters
70    ///
71    /// * `t` - Reference to the input value
72    ///
73    /// # Returns
74    ///
75    /// The computed output value
76    fn apply(self, t: &T) -> R;
77
78    /// Converts to BoxFunctionOnce
79    ///
80    /// **⚠️ Consumes `self`**: The original function becomes unavailable
81    /// after calling this method.
82    ///
83    /// # Returns
84    ///
85    /// Returns `BoxFunctionOnce<T, R>`
86    ///
87    /// # Examples
88    ///
89    /// ```rust
90    /// use qubit_function::FunctionOnce;
91    ///
92    /// let double = |x: &i32| x * 2;
93    /// let boxed = double.into_box();
94    /// assert_eq!(boxed.apply(&21), 42);
95    /// ```
96    fn into_box(self) -> BoxFunctionOnce<T, R>
97    where
98        Self: Sized + 'static,
99    {
100        BoxFunctionOnce::new(move |input: &T| self.apply(input))
101    }
102
103    /// Converts function to a closure
104    ///
105    /// **⚠️ Consumes `self`**: The original function becomes unavailable
106    /// after calling this method.
107    ///
108    /// # Returns
109    ///
110    /// Returns a closure that implements `FnOnce(&T) -> R`
111    ///
112    /// # Examples
113    ///
114    /// ```rust
115    /// use qubit_function::FunctionOnce;
116    ///
117    /// let double = |x: &i32| x * 2;
118    /// let func = double.into_fn();
119    /// assert_eq!(func(&21), 42);
120    /// ```
121    fn into_fn(self) -> impl FnOnce(&T) -> R
122    where
123        Self: Sized + 'static,
124    {
125        move |input: &T| self.apply(input)
126    }
127
128    /// Converts to BoxFunctionOnce without consuming self
129    ///
130    /// **📌 Borrows `&self`**: The original function remains usable
131    /// after calling this method.
132    ///
133    /// # Default Implementation
134    ///
135    /// The default implementation creates a new `BoxFunctionOnce` that
136    /// captures a clone. Types implementing `Clone` can override this method
137    /// to provide more efficient conversions.
138    ///
139    /// # Returns
140    ///
141    /// Returns `BoxFunctionOnce<T, R>`
142    ///
143    /// # Examples
144    ///
145    /// ```rust
146    /// use qubit_function::FunctionOnce;
147    ///
148    /// let double = |x: &i32| x * 2;
149    /// let boxed = double.to_box();
150    /// assert_eq!(boxed.apply(&21), 42);
151    /// ```
152    fn to_box(&self) -> BoxFunctionOnce<T, R>
153    where
154        Self: Clone + 'static,
155    {
156        self.clone().into_box()
157    }
158
159    /// Converts function to a closure without consuming self
160    ///
161    /// **📌 Borrows `&self`**: The original function remains usable
162    /// after calling this method.
163    ///
164    /// # Default Implementation
165    ///
166    /// The default implementation creates a closure that captures a
167    /// clone of `self` and calls its `apply` method. Types can
168    /// override this method to provide more efficient conversions.
169    ///
170    /// # Returns
171    ///
172    /// Returns a closure that implements `FnOnce(&T) -> R`
173    ///
174    /// # Examples
175    ///
176    /// ```rust
177    /// use qubit_function::FunctionOnce;
178    ///
179    /// let double = |x: &i32| x * 2;
180    /// let func = double.to_fn();
181    /// assert_eq!(func(&21), 42);
182    /// ```
183    fn to_fn(&self) -> impl FnOnce(&T) -> R
184    where
185        Self: Clone + 'static,
186    {
187        self.clone().into_fn()
188    }
189}