Skip to main content

qubit_function/functions/
bi_function_once.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9
10//! # BiFunctionOnce Types
11//!
12//! Provides Rust implementations of consuming bi-function traits similar to
13//! Rust's `FnOnce(&T, &U) -> R` trait, but with value-oriented semantics for functional
14//! programming patterns with two input references.
15//!
16//! This module provides the `BiFunctionOnce<T, U, R>` trait and one-time use
17//! implementations:
18//!
19//! - [`BoxBiFunctionOnce`]: Single ownership, one-time use
20//!
21//! # Author
22//!
23//! Haixing Hu
24use crate::macros::{
25    impl_box_once_conversions,
26    impl_closure_once_trait,
27};
28use crate::predicates::bi_predicate::{
29    BiPredicate,
30    BoxBiPredicate,
31};
32use crate::{
33    functions::function_once::FunctionOnce,
34    functions::macros::{
35        impl_box_conditional_function,
36        impl_box_function_methods,
37        impl_conditional_function_debug_display,
38        impl_function_common_methods,
39        impl_function_constant_method,
40        impl_function_debug_display,
41    },
42};
43
44mod box_bi_function_once;
45pub use box_bi_function_once::BoxBiFunctionOnce;
46mod fn_bi_function_once_ops;
47pub use fn_bi_function_once_ops::FnBiFunctionOnceOps;
48mod box_conditional_bi_function_once;
49pub use box_conditional_bi_function_once::BoxConditionalBiFunctionOnce;
50
51// ============================================================================
52// Core Trait
53// ============================================================================
54
55/// BiFunctionOnce trait - consuming bi-function that takes references
56///
57/// Defines the behavior of a consuming bi-function: computing a value of
58/// type `R` from references to types `T` and `U` by taking ownership of self.
59/// This trait is analogous to `FnOnce(&T, &U) -> R`.
60///
61/// # Type Parameters
62///
63/// * `T` - The type of the first input value (borrowed)
64/// * `U` - The type of the second input value (borrowed)
65/// * `R` - The type of the output value
66///
67/// # Author
68///
69/// Haixing Hu
70pub trait BiFunctionOnce<T, U, R> {
71    /// Computes output from two input references, consuming self
72    ///
73    /// # Parameters
74    ///
75    /// * `first` - Reference to the first input value
76    /// * `second` - Reference to the second input value
77    ///
78    /// # Returns
79    ///
80    /// The computed output value
81    fn apply(self, first: &T, second: &U) -> R;
82
83    /// Converts to BoxBiFunctionOnce
84    ///
85    /// **⚠️ Consumes `self`**: The original bi-function becomes unavailable
86    /// after calling this method.
87    ///
88    /// # Returns
89    ///
90    /// Returns `BoxBiFunctionOnce<T, U, R>`
91    fn into_box(self) -> BoxBiFunctionOnce<T, U, R>
92    where
93        Self: Sized + 'static,
94    {
95        BoxBiFunctionOnce::new(move |t: &T, u: &U| self.apply(t, u))
96    }
97
98    /// Converts bi-function to a closure
99    ///
100    /// **⚠️ Consumes `self`**: The original bi-function becomes unavailable
101    /// after calling this method.
102    ///
103    /// # Returns
104    ///
105    /// Returns a closure that implements `FnOnce(&T, &U) -> R`
106    fn into_fn(self) -> impl FnOnce(&T, &U) -> R
107    where
108        Self: Sized + 'static,
109    {
110        move |t: &T, u: &U| self.apply(t, u)
111    }
112
113    /// Converts bi-function to a boxed function pointer
114    ///
115    /// **📌 Borrows `&self`**: The original bi-function remains usable
116    /// after calling this method.
117    ///
118    /// # Returns
119    ///
120    /// Returns a boxed function pointer that implements `FnOnce(&T, &U) -> R`
121    ///
122    /// # Examples
123    ///
124    /// ```rust
125    /// use qubit_function::BiFunctionOnce;
126    ///
127    /// let add = |x: &i32, y: &i32| *x + *y;
128    /// let func = add.to_box();
129    /// assert_eq!(func.apply(&20, &22), 42);
130    /// ```
131    fn to_box(&self) -> BoxBiFunctionOnce<T, U, R>
132    where
133        Self: Clone + 'static,
134    {
135        self.clone().into_box()
136    }
137
138    /// Converts bi-function to a closure
139    ///
140    /// **📌 Borrows `&self`**: The original bi-function remains usable
141    /// after calling this method.
142    ///
143    /// # Returns
144    ///
145    /// Returns a closure that implements `FnOnce(&T, &U) -> R`
146    ///
147    /// # Examples
148    ///
149    /// ```rust
150    /// use qubit_function::BiFunctionOnce;
151    ///
152    /// let add = |x: &i32, y: &i32| *x + *y;
153    /// let func = add.to_fn();
154    /// assert_eq!(func(&20, &22), 42);
155    /// ```
156    fn to_fn(&self) -> impl FnOnce(&T, &U) -> R
157    where
158        Self: Clone + 'static,
159    {
160        self.clone().into_fn()
161    }
162}