Skip to main content

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}