prism3_function/macros/box_conversions.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025.
4 * 3-Prism 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 fn into_box(self) -> $box_type<$($generics),*>
72 where
73 $($generics: 'static),*
74 {
75 self
76 }
77
78 fn into_rc(self) -> $rc_type<$($generics),*>
79 where
80 $($generics: 'static),*
81 {
82 $rc_type::new_with_optional_name(self.function, self.name)
83 }
84
85 fn into_fn(self) -> impl $fn_trait
86 {
87 self.function
88 }
89 };
90
91 // 4-parameter pattern: box_type, rc_type, fn_trait, once_type
92 // Reuse 3-parameter version to generate into_box, into_rc, into_fn
93 (
94 $box_type:ident < $($generics:ident),* >,
95 $rc_type:ident,
96 $fn_trait:path,
97 $once_type:ident
98 ) => {
99 // Reuse 3-parameter version to generate into_box, into_rc, into_fn
100 impl_box_conversions!(
101 $box_type < $($generics),* >,
102 $rc_type,
103 $fn_trait
104 );
105
106 fn into_once(self) -> $once_type<$($generics),*>
107 where
108 $($generics: 'static),*
109 {
110 $once_type::new_with_optional_name(self.function, self.name)
111 }
112 };
113}
114
115pub(crate) use impl_box_conversions;
116
117/// Implement common conversion methods for Box*Once types
118///
119/// This macro generates standard conversion methods for all Box*Once types
120/// that implement their respective traits (into_box, into_fn).
121///
122/// The macro unifies the pattern for both void-returning functions (like
123/// Consumer, Mutator) and value-returning functions (like Function,
124/// Transformer, Supplier).
125///
126/// # Parameters
127///
128/// * `$box_type_with_generics` - Box type with generics (e.g.,
129/// `BoxConsumerOnce<T>`, `BoxBiConsumerOnce<T, U>`)
130/// * `$trait_name` - Trait name (for documentation, unused in expansion)
131/// * `$fn_trait` - Function trait type (e.g., `FnOnce(&T)`,
132/// `FnOnce(&T) -> R`, `FnOnce() -> T`)
133///
134/// # Generated methods
135///
136/// * `into_box(self) -> BoxType` - Zero-cost conversion, returns self
137/// * `into_fn(self) -> impl FnOnce(...)` - Extract underlying function
138///
139/// # Examples
140///
141/// ```ignore
142/// // Consumer: (&T) -> ()
143/// impl_box_once_conversions!(BoxConsumerOnce<T>, ConsumerOnce, FnOnce(&T));
144///
145/// // BiConsumer: (&T, &U) -> ()
146/// impl_box_once_conversions!(BoxBiConsumerOnce<T, U>, BiConsumerOnce,
147/// FnOnce(&T, &U));
148///
149/// // Function: (&T) -> R
150/// impl_box_once_conversions!(BoxFunctionOnce<T, R>, FunctionOnce,
151/// FnOnce(&T) -> R);
152///
153/// // Transformer: (T) -> R
154/// impl_box_once_conversions!(BoxTransformerOnce<T, R>, TransformerOnce,
155/// FnOnce(T) -> R);
156///
157/// // Supplier: () -> T
158/// impl_box_once_conversions!(BoxSupplierOnce<T>, SupplierOnce, FnOnce() -> T);
159/// ```
160///
161/// # Author
162///
163/// Hu Haixing
164macro_rules! impl_box_once_conversions {
165 (
166 $box_type:ident < $($generics:ident),* >,
167 $trait_name:ident,
168 $fn_trait:path
169 ) => {
170 fn into_box(self) -> $box_type<$($generics),*>
171 where
172 $($generics: 'static),*
173 {
174 self
175 }
176
177 fn into_fn(self) -> impl $fn_trait
178 where
179 $($generics: 'static),*
180 {
181 self.function
182 }
183 };
184}
185
186pub(crate) use impl_box_once_conversions;