Skip to main content

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