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