Skip to main content

qubit_function/macros/
box_conversions.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Box Conversions Macro
10//!
11//! Generate common conversion methods for all Box-based function wrappers.
12//!
13//! This macro uses a unified pattern to generate standard conversion methods
14//! for all Box-based function wrapper types (into_box, into_rc, into_fn,
15//! into_once).
16//!
17//! # Author
18//!
19//! Hu Haixing
20
21/// Implement common conversion methods for Box types
22///
23/// This macro generates standard conversion methods for Box-based function
24/// wrappers.
25///
26/// # Parameters
27///
28/// * `$box_type<$(generics),*>` - Box wrapper type (e.g., `BoxConsumer<T>`)
29/// * `$rc_type` - Corresponding Rc wrapper type (e.g., `RcConsumer`)
30/// * `$fn_trait` - Function trait (e.g., `Fn(&T)`, `Fn(&T) -> bool`)
31/// * `$once_type` - Corresponding once wrapper type (optional, e.g.,
32///   `BoxConsumerOnce`)
33///
34/// # Generated methods
35///
36/// * `into_box(self) -> BoxType` - Zero-cost conversion, returns self
37/// * `into_rc(self) -> RcType` - Convert to Rc-based wrapper
38/// * `into_fn(self) -> impl FnTrait` - Extract underlying function
39/// * `into_once(self) -> OnceType` - Convert to once wrapper (only when
40///   once_type is provided)
41///
42/// # Examples
43///
44/// ```ignore
45/// // 3-parameter version (no once type)
46/// impl_box_conversions!(
47///     BoxPredicate<T>,
48///     RcPredicate,
49///     Fn(&T) -> bool
50/// );
51///
52/// // 4-parameter version (with once type)
53/// impl_box_conversions!(
54///     BoxConsumer<T>,
55///     RcConsumer,
56///     Fn(&T),
57///     BoxConsumerOnce
58/// );
59/// ```
60///
61/// # Author
62///
63/// Hu Haixing
64macro_rules! impl_box_conversions {
65    // 3-parameter pattern: box_type, rc_type, fn_trait (no once_type)
66    (
67        $box_type:ident < $($generics:ident),* >,
68        $rc_type:ident,
69        $fn_trait:path
70    ) => {
71        #[inline]
72        fn into_box(self) -> $box_type<$($generics),*>
73        where
74            $($generics: 'static),*
75        {
76            self
77        }
78
79        #[inline]
80        fn into_rc(self) -> $rc_type<$($generics),*>
81        where
82            $($generics: 'static),*
83        {
84            $rc_type::new_with_optional_name(self.function, self.name)
85        }
86
87        #[inline]
88        fn into_fn(self) -> impl $fn_trait
89        {
90            self.function
91        }
92    };
93
94    // 4-parameter pattern: box_type, rc_type, fn_trait, once_type
95    // Reuse 3-parameter version to generate into_box, into_rc, into_fn
96    (
97        $box_type:ident < $($generics:ident),* >,
98        $rc_type:ident,
99        $fn_trait:path,
100        $once_type:ident
101    ) => {
102        // Reuse 3-parameter version to generate into_box, into_rc, into_fn
103        impl_box_conversions!(
104            $box_type < $($generics),* >,
105            $rc_type,
106            $fn_trait
107        );
108
109        #[inline]
110        fn into_once(self) -> $once_type<$($generics),*>
111        where
112            $($generics: 'static),*
113        {
114            $once_type::new_with_optional_name(self.function, self.name)
115        }
116    };
117}
118
119pub(crate) use impl_box_conversions;
120
121/// Implement common conversion methods for Box*Once types
122///
123/// This macro generates standard conversion methods for all Box*Once types
124/// that implement their respective traits (into_box, into_fn).
125///
126/// The macro unifies the pattern for both void-returning functions (like
127/// Consumer, Mutator) and value-returning functions (like Function,
128/// Transformer, Supplier).
129///
130/// # Parameters
131///
132/// * `$box_type_with_generics` - Box type with generics (e.g.,
133///   `BoxConsumerOnce<T>`, `BoxBiConsumerOnce<T, U>`)
134/// * `$trait_name` - Trait name (for documentation, unused in expansion)
135/// * `$fn_trait` - Function trait type (e.g., `FnOnce(&T)`,
136///   `FnOnce(&T) -> R`, `FnOnce() -> T`)
137///
138/// # Generated methods
139///
140/// * `into_box(self) -> BoxType` - Zero-cost conversion, returns self
141/// * `into_fn(self) -> impl FnOnce(...)` - Extract underlying function
142///
143/// # Examples
144///
145/// ```ignore
146/// // Consumer: (&T) -> ()
147/// impl_box_once_conversions!(BoxConsumerOnce<T>, ConsumerOnce, FnOnce(&T));
148///
149/// // BiConsumer: (&T, &U) -> ()
150/// impl_box_once_conversions!(BoxBiConsumerOnce<T, U>, BiConsumerOnce,
151///     FnOnce(&T, &U));
152///
153/// // Function: (&T) -> R
154/// impl_box_once_conversions!(BoxFunctionOnce<T, R>, FunctionOnce,
155///     FnOnce(&T) -> R);
156///
157/// // Transformer: (T) -> R
158/// impl_box_once_conversions!(BoxTransformerOnce<T, R>, TransformerOnce,
159///     FnOnce(T) -> R);
160///
161/// // Supplier: () -> T
162/// impl_box_once_conversions!(BoxSupplierOnce<T>, SupplierOnce, FnOnce() -> T);
163/// ```
164///
165/// # Author
166///
167/// Hu Haixing
168macro_rules! impl_box_once_conversions {
169    (
170        $box_type:ident < $($generics:ident),* >,
171        $trait_name:ident,
172        $fn_trait:path
173    ) => {
174        #[inline]
175        fn into_box(self) -> $box_type<$($generics),*>
176        where
177            $($generics: 'static),*
178        {
179            self
180        }
181
182        #[inline]
183        fn into_fn(self) -> impl $fn_trait
184        where
185            $($generics: 'static),*
186        {
187            self.function
188        }
189    };
190}
191
192pub(crate) use impl_box_once_conversions;