Skip to main content

qubit_function/transformers/
bi_transformer.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # BiTransformer Types
10//!
11//! Provides Rust implementations of bi-transformer traits for type conversion
12//! and value transformation with two inputs. BiTransformers consume two input
13//! values (taking ownership) and produce an output value.
14//!
15//! This module provides the `BiTransformer<T, U, R>` trait and three
16//! implementations:
17//!
18//! - [`BoxBiTransformer`]: Single ownership, not cloneable
19//! - [`ArcBiTransformer`]: Thread-safe shared ownership, cloneable
20//! - [`RcBiTransformer`]: Single-threaded shared ownership, cloneable
21//!
22//! # Author
23//!
24//! Haixing Hu
25use std::rc::Rc;
26use std::sync::Arc;
27
28use crate::macros::{
29    impl_arc_conversions,
30    impl_box_conversions,
31    impl_rc_conversions,
32};
33use crate::predicates::bi_predicate::{
34    ArcBiPredicate,
35    BiPredicate,
36    BoxBiPredicate,
37    RcBiPredicate,
38};
39use crate::transformers::{
40    bi_transformer_once::BoxBiTransformerOnce,
41    macros::{
42        impl_box_conditional_transformer,
43        impl_box_transformer_methods,
44        impl_conditional_transformer_clone,
45        impl_conditional_transformer_debug_display,
46        impl_shared_conditional_transformer,
47        impl_shared_transformer_methods,
48        impl_transformer_clone,
49        impl_transformer_common_methods,
50        impl_transformer_constant_method,
51        impl_transformer_debug_display,
52    },
53    transformer::Transformer,
54};
55
56mod box_bi_transformer;
57pub use box_bi_transformer::BoxBiTransformer;
58mod rc_bi_transformer;
59pub use rc_bi_transformer::RcBiTransformer;
60mod arc_bi_transformer;
61pub use arc_bi_transformer::ArcBiTransformer;
62mod fn_bi_transformer_ops;
63pub use fn_bi_transformer_ops::FnBiTransformerOps;
64mod binary_operator;
65pub use binary_operator::BinaryOperator;
66mod box_binary_operator;
67pub use box_binary_operator::BoxBinaryOperator;
68mod arc_binary_operator;
69pub use arc_binary_operator::ArcBinaryOperator;
70mod rc_binary_operator;
71pub use rc_binary_operator::RcBinaryOperator;
72mod box_conditional_bi_transformer;
73pub use box_conditional_bi_transformer::BoxConditionalBiTransformer;
74mod rc_conditional_bi_transformer;
75pub use rc_conditional_bi_transformer::RcConditionalBiTransformer;
76mod arc_conditional_bi_transformer;
77pub use arc_conditional_bi_transformer::ArcConditionalBiTransformer;
78
79// ============================================================================
80// Core Trait
81// ============================================================================
82
83/// BiTransformer trait - transforms two values to produce a result
84///
85/// Defines the behavior of a bi-transformation: converting two values of types
86/// `T` and `U` to a value of type `R` by consuming the inputs. This is
87/// analogous to `Fn(T, U) -> R` in Rust's standard library.
88///
89/// # Type Parameters
90///
91/// * `T` - The type of the first input value (consumed)
92/// * `U` - The type of the second input value (consumed)
93/// * `R` - The type of the output value
94///
95/// # Author
96///
97/// Haixing Hu
98pub trait BiTransformer<T, U, R> {
99    /// Transforms two input values to produce an output value
100    ///
101    /// # Parameters
102    ///
103    /// * `first` - The first input value to transform (consumed)
104    /// * `second` - The second input value to transform (consumed)
105    ///
106    /// # Returns
107    ///
108    /// The transformed output value
109    fn apply(&self, first: T, second: U) -> R;
110
111    /// Converts to BoxBiTransformer
112    ///
113    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
114    /// after calling this method.
115    ///
116    /// # Default Implementation
117    ///
118    /// The default implementation wraps `self` in a `Box` and creates a
119    /// `BoxBiTransformer`. Types can override this method to provide more
120    /// efficient conversions.
121    ///
122    /// # Returns
123    ///
124    /// Returns `BoxBiTransformer<T, U, R>`
125    fn into_box(self) -> BoxBiTransformer<T, U, R>
126    where
127        Self: Sized + 'static,
128    {
129        BoxBiTransformer::new(move |x, y| self.apply(x, y))
130    }
131
132    /// Converts to RcBiTransformer
133    ///
134    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
135    /// after calling this method.
136    ///
137    /// # Default Implementation
138    ///
139    /// The default implementation wraps `self` in an `Rc` and creates an
140    /// `RcBiTransformer`. Types can override this method to provide more
141    /// efficient conversions.
142    ///
143    /// # Returns
144    ///
145    /// Returns `RcBiTransformer<T, U, R>`
146    fn into_rc(self) -> RcBiTransformer<T, U, R>
147    where
148        Self: Sized + 'static,
149    {
150        RcBiTransformer::new(move |x, y| self.apply(x, y))
151    }
152
153    /// Converts to ArcBiTransformer
154    ///
155    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
156    /// after calling this method.
157    ///
158    /// # Default Implementation
159    ///
160    /// The default implementation wraps `self` in an `Arc` and creates an
161    /// `ArcBiTransformer`. Types can override this method to provide more
162    /// efficient conversions.
163    ///
164    /// # Returns
165    ///
166    /// Returns `ArcBiTransformer<T, U, R>`
167    fn into_arc(self) -> ArcBiTransformer<T, U, R>
168    where
169        Self: Sized + Send + Sync + 'static,
170    {
171        ArcBiTransformer::new(move |x, y| self.apply(x, y))
172    }
173
174    /// Converts bi-transformer to a closure
175    ///
176    /// **⚠️ Consumes `self`**: The original bi-transformer becomes unavailable
177    /// after calling this method.
178    ///
179    /// # Default Implementation
180    ///
181    /// The default implementation creates a closure that captures `self`
182    /// and calls its `apply` method. Types can override this method
183    /// to provide more efficient conversions.
184    ///
185    /// # Returns
186    ///
187    /// Returns a closure that implements `Fn(T, U) -> R`
188    fn into_fn(self) -> impl Fn(T, U) -> R
189    where
190        Self: Sized + 'static,
191    {
192        move |t, u| self.apply(t, u)
193    }
194
195    /// Convert to BiTransformerOnce
196    ///
197    /// **⚠️ Consumes `self`**: The original bi-transformer will be unavailable after calling this method.
198    ///
199    /// Converts a reusable bi-transformer to a one-time bi-transformer that consumes itself on use.
200    /// This enables passing `BiTransformer` to functions that require `BiTransformerOnce`.
201    ///
202    /// # Returns
203    ///
204    /// Returns a `BoxBiTransformerOnce<T, U, R>`
205    fn into_once(self) -> BoxBiTransformerOnce<T, U, R>
206    where
207        Self: Sized + 'static,
208    {
209        BoxBiTransformerOnce::new(move |t, u| self.apply(t, u))
210    }
211
212    /// Non-consuming conversion to `BoxBiTransformer` using `&self`.
213    ///
214    /// Default implementation clones `self` and delegates to `into_box`.
215    fn to_box(&self) -> BoxBiTransformer<T, U, R>
216    where
217        Self: Sized + Clone + 'static,
218    {
219        self.clone().into_box()
220    }
221
222    /// Non-consuming conversion to `RcBiTransformer` using `&self`.
223    ///
224    /// Default implementation clones `self` and delegates to `into_rc`.
225    fn to_rc(&self) -> RcBiTransformer<T, U, R>
226    where
227        Self: Sized + Clone + 'static,
228    {
229        self.clone().into_rc()
230    }
231
232    /// Non-consuming conversion to `ArcBiTransformer` using `&self`.
233    ///
234    /// Default implementation clones `self` and delegates to `into_arc`.
235    fn to_arc(&self) -> ArcBiTransformer<T, U, R>
236    where
237        Self: Sized + Clone + Send + Sync + 'static,
238    {
239        self.clone().into_arc()
240    }
241
242    /// Non-consuming conversion to a boxed function using `&self`.
243    ///
244    /// Returns a `Box<dyn Fn(T, U) -> R>` that clones `self` and calls
245    /// `apply` inside the boxed closure.
246    fn to_fn(&self) -> impl Fn(T, U) -> R
247    where
248        Self: Sized + Clone + 'static,
249    {
250        self.clone().into_fn()
251    }
252
253    /// Convert to BiTransformerOnce without consuming self
254    ///
255    /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
256    /// Clones the current bi-transformer and converts the clone to a one-time bi-transformer.
257    ///
258    /// # Returns
259    ///
260    /// Returns a `BoxBiTransformerOnce<T, U, R>`
261    fn to_once(&self) -> BoxBiTransformerOnce<T, U, R>
262    where
263        Self: Clone + 'static,
264    {
265        self.clone().into_once()
266    }
267}