prism3_function/macros/
closure_trait.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9
10/// Implement trait for closures with automatic type inference
11///
12/// This macro generates blanket implementations for closures implementing
13/// various function traits (Consumer, Function, Predicate, etc.). It
14/// automatically infers everything from the function signature and trait name.
15///
16/// # Parameters
17///
18/// * `$trait_name<$(generics),*>` - Full trait name with generics (e.g., `Consumer<T>`, `Function<T, R>`)
19/// * `$method_name` - Core method name (e.g., `accept`, `apply`, `test`)
20/// * `$once_type` - Optional once wrapper type (e.g., `BoxConsumerOnce`)
21/// * `$fn_signature` - Function signature (e.g., `Fn(value: &T)`, `FnMut(input: &T) -> R`)
22///
23/// # Generated implementation
24///
25/// Generates a blanket implementation for all closures matching the signature,
26/// including:
27/// - Core method implementation
28/// - `into_box`, `into_rc`, `into_arc`, `into_fn` methods
29/// - `to_box`, `to_rc`, `to_arc`, `to_fn` methods
30/// - `into_once`, `to_once` methods (if once_type is provided)
31///
32/// # Examples
33///
34/// ```ignore
35/// // Consumer trait (with once conversion)
36/// impl_closure_trait!(
37///     Consumer<T>,
38///     accept,
39///     BoxConsumerOnce,
40///     Fn(value: &T)
41/// );
42///
43/// // Function trait
44/// impl_closure_trait!(
45///     Function<T, R>,
46///     apply,
47///     BoxFunctionOnce,
48///     Fn(input: &T) -> R
49/// );
50///
51/// // Predicate trait (no once conversion)
52/// impl_closure_trait!(
53///     Predicate<T>,
54///     test,
55///     Fn(value: &T) -> bool
56/// );
57///
58/// // StatefulConsumer trait
59/// impl_closure_trait!(
60///     StatefulConsumer<T>,
61///     accept,
62///     BoxConsumerOnce,
63///     FnMut(value: &T)
64/// );
65/// ```
66///
67/// # Author
68///
69/// Haixing Hu
70macro_rules! impl_closure_trait {
71  // ==================== 辅助宏:生成 into_once 方法 ====================
72
73  // Fn trait: into_once 方法
74  (@into_once_fn_method $once_type:ident, ($($generics:ident),*)) => {
75      fn into_once(self) -> $once_type<$($generics),*>
76      where
77          Self: Sized + 'static,
78          $($generics: 'static,)*
79      {
80          $once_type::new(self)
81      }
82  };
83
84  // FnMut trait: into_once 方法
85  (@into_once_fnmut_method $once_type:ident, ($($generics:ident),*), ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?) => {
86      fn into_once(mut self) -> $once_type<$($generics),*>
87      where
88          Self: Sized + 'static,
89          $($generics: 'static,)*
90      {
91          $once_type::new(move |$($arg: $arg_ty),*| self($($arg),*))
92      }
93  };
94
95  // ==================== 辅助宏:生成 to_once 方法 ====================
96
97  // Fn trait: to_once 方法
98  (@to_once_fn_method $once_type:ident, ($($generics:ident),*)) => {
99      fn to_once(&self) -> $once_type<$($generics),*>
100      where
101          Self: Clone + Sized + 'static,
102          $($generics: 'static,)*
103      {
104          $once_type::new(self.clone())
105      }
106  };
107
108  // FnMut trait: to_once 方法
109  (@to_once_fnmut_method $once_type:ident, ($($generics:ident),*), ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?) => {
110      fn to_once(&self) -> $once_type<$($generics),*>
111      where
112          Self: Clone + Sized + 'static,
113          $($generics: 'static,)*
114      {
115          let mut cloned = self.clone();
116          $once_type::new(move |$($arg: $arg_ty),*| cloned($($arg),*))
117      }
118  };
119
120  // ==================== 内部实现:通用部分(Fn trait)====================
121
122  (
123      @impl_common_fn
124      $trait_name:ident < $($generics:ident),* >,
125      $method_name:ident,
126      $closure_trait:path,
127      ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
128  ) => {
129      // 核心方法:直接调用闭包
130      fn $method_name(&self, $($arg: $arg_ty),*) $(-> $ret)? {
131          self($($arg),*)
132      }
133
134      // ===== 转换方法:使用 paste 自动推导类型名 =====
135
136      fn into_box(self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
137      where
138          Self: Sized + 'static,
139      {
140          paste::paste! { [<Box $trait_name>]::new(self) }
141      }
142
143      fn into_rc(self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
144      where
145          Self: Sized + 'static,
146      {
147          paste::paste! { [<Rc $trait_name>]::new(self) }
148      }
149
150      fn into_fn(self) -> impl $closure_trait
151      where
152          Self: Sized + 'static,
153      {
154          self
155      }
156
157      // into_arc: Fn trait 需要 Send + Sync
158      fn into_arc(self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
159      where
160          Self: Sized + Send + Sync + 'static,
161          $($generics: 'static,)*
162      {
163          paste::paste! { [<Arc $trait_name>]::new(self) }
164      }
165
166      // ===== to_* 方法:克隆版本 =====
167
168      fn to_box(&self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
169      where
170          Self: Clone + Sized + 'static,
171      {
172          paste::paste! { [<Box $trait_name>]::new(self.clone()) }
173      }
174
175      fn to_rc(&self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
176      where
177          Self: Clone + Sized + 'static,
178      {
179          paste::paste! { [<Rc $trait_name>]::new(self.clone()) }
180      }
181
182      fn to_fn(&self) -> impl $closure_trait
183      where
184          Self: Clone + Sized + 'static,
185      {
186          self.clone()
187      }
188
189      // to_arc: Fn trait 需要 Send + Sync
190      fn to_arc(&self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
191      where
192          Self: Clone + Sized + Send + Sync + 'static,
193          $($generics: 'static,)*
194      {
195          paste::paste! { [<Arc $trait_name>]::new(self.clone()) }
196      }
197  };
198
199  // ==================== 内部实现:通用部分(FnMut trait)====================
200
201  (
202      @impl_common_fnmut
203      $trait_name:ident < $($generics:ident),* >,
204      $method_name:ident,
205      $closure_trait:path,
206      ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
207  ) => {
208      // 核心方法:直接调用闭包
209      fn $method_name(&mut self, $($arg: $arg_ty),*) $(-> $ret)? {
210          self($($arg),*)
211      }
212
213      // ===== 转换方法:使用 paste 自动推导类型名 =====
214
215      fn into_box(self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
216      where
217          Self: Sized + 'static,
218      {
219          paste::paste! { [<Box $trait_name>]::new(self) }
220      }
221
222      fn into_rc(self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
223      where
224          Self: Sized + 'static,
225      {
226          paste::paste! { [<Rc $trait_name>]::new(self) }
227      }
228
229      fn into_fn(self) -> impl $closure_trait
230      where
231          Self: Sized + 'static,
232      {
233          self
234      }
235
236      // into_arc: FnMut trait 只需要 Send
237      fn into_arc(self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
238      where
239          Self: Sized + Send + 'static,
240          $($generics: 'static,)*
241      {
242          paste::paste! { [<Arc $trait_name>]::new(self) }
243      }
244
245      // ===== to_* 方法:克隆版本 =====
246
247      fn to_box(&self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
248      where
249          Self: Clone + Sized + 'static,
250      {
251          paste::paste! { [<Box $trait_name>]::new(self.clone()) }
252      }
253
254      fn to_rc(&self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
255      where
256          Self: Clone + Sized + 'static,
257      {
258          paste::paste! { [<Rc $trait_name>]::new(self.clone()) }
259      }
260
261      fn to_fn(&self) -> impl $closure_trait
262      where
263          Self: Clone + Sized + 'static,
264      {
265          self.clone()
266      }
267
268      // to_arc: FnMut trait 只需要 Send
269      fn to_arc(&self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
270      where
271          Self: Clone + Sized + Send + 'static,
272          $($generics: 'static,)*
273      {
274          let cloned = self.clone();
275          paste::paste! { [<Arc $trait_name>]::new(cloned) }
276      }
277  };
278
279
280  // ==================== 公共接口:参考 impl_rc_conversions 的模式 ====================
281
282  // Regular trait (Fn) - with once conversion
283  (
284      $trait_name:ident < $($generics:ident),* >,
285      $method_name:ident,
286      $once_type:ident,
287      Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
288  ) => {
289      impl<$($generics,)* F> $trait_name<$($generics),*> for F
290      where
291          F: Fn($($arg_ty),*) $(-> $ret)?,
292          $($generics: 'static,)*
293      {
294          // 生成通用方法
295          impl_closure_trait!(
296              @impl_common_fn
297              $trait_name<$($generics),*>,
298              $method_name,
299              Fn($($arg_ty),*) $(-> $ret)?,
300              ($($arg : $arg_ty),*) $(-> $ret)?
301          );
302
303          // 生成 into_once 和 to_once 方法
304          impl_closure_trait!(@into_once_fn_method $once_type, ($($generics),*));
305          impl_closure_trait!(@to_once_fn_method $once_type, ($($generics),*));
306      }
307  };
308
309  // Regular trait (Fn) - without once version
310  (
311      $trait_name:ident < $($generics:ident),* >,
312      $method_name:ident,
313      Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
314  ) => {
315      impl<$($generics,)* F> $trait_name<$($generics),*> for F
316      where
317          F: Fn($($arg_ty),*) $(-> $ret)?,
318          $($generics: 'static,)*
319      {
320          // 生成通用方法(不包含 into_once/to_once)
321          impl_closure_trait!(
322              @impl_common_fn
323              $trait_name<$($generics),*>,
324              $method_name,
325              Fn($($arg_ty),*) $(-> $ret)?,
326              ($($arg : $arg_ty),*) $(-> $ret)?
327          );
328      }
329  };
330
331  // Stateful trait (FnMut) - with once conversion
332  (
333      $trait_name:ident < $($generics:ident),* >,
334      $method_name:ident,
335      $once_type:ident,
336      FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
337  ) => {
338      impl<$($generics,)* F> $trait_name<$($generics),*> for F
339      where
340          F: FnMut($($arg_ty),*) $(-> $ret)?,
341          $($generics: 'static,)*
342      {
343          // 生成通用方法
344          impl_closure_trait!(
345              @impl_common_fnmut
346              $trait_name<$($generics),*>,
347              $method_name,
348              FnMut($($arg_ty),*) $(-> $ret)?,
349              ($($arg : $arg_ty),*) $(-> $ret)?
350          );
351
352          // 生成 into_once 和 to_once 方法
353          impl_closure_trait!(@into_once_fnmut_method $once_type, ($($generics),*), ($($arg : $arg_ty),*) $(-> $ret)?);
354          impl_closure_trait!(@to_once_fnmut_method $once_type, ($($generics),*), ($($arg : $arg_ty),*) $(-> $ret)?);
355      }
356  };
357
358  // Stateful trait (FnMut) - without once version
359  (
360      $trait_name:ident < $($generics:ident),* >,
361      $method_name:ident,
362      FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
363  ) => {
364      impl<$($generics,)* F> $trait_name<$($generics),*> for F
365      where
366          F: FnMut($($arg_ty),*) $(-> $ret)?,
367          $($generics: 'static,)*
368      {
369          // 生成通用方法(不包含 into_once/to_once)
370          impl_closure_trait!(
371              @impl_common_fnmut
372              $trait_name<$($generics),*>,
373              $method_name,
374              FnMut($($arg_ty),*) $(-> $ret)?,
375              ($($arg : $arg_ty),*) $(-> $ret)?
376          );
377      }
378  };
379}
380
381pub(crate) use impl_closure_trait;