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