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}