Skip to main content

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}