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}