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}