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