Skip to main content

qubit_function/macros/
closure_trait.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit 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      #[inline]
76      fn into_once(self) -> $once_type<$($generics),*>
77      where
78          Self: Sized + '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      #[inline]
87      fn into_once(mut self) -> $once_type<$($generics),*>
88      where
89          Self: Sized + '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      #[inline]
100      fn to_once(&self) -> $once_type<$($generics),*>
101      where
102          Self: Clone + Sized + '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      #[inline]
111      fn to_once(&self) -> $once_type<$($generics),*>
112      where
113          Self: Clone + Sized + '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      #[inline]
131      fn $method_name(&self, $($arg: $arg_ty),*) $(-> $ret)? {
132          self($($arg),*)
133      }
134
135      // ===== 转换方法:使用 paste 自动推导类型名 =====
136
137      #[inline]
138      fn into_box(self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
139      where
140          Self: Sized + 'static,
141      {
142          paste::paste! { [<Box $trait_name>]::new(self) }
143      }
144
145      #[inline]
146      fn into_rc(self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
147      where
148          Self: Sized + 'static,
149      {
150          paste::paste! { [<Rc $trait_name>]::new(self) }
151      }
152
153      #[inline]
154      fn into_fn(self) -> impl $closure_trait
155      where
156          Self: Sized + 'static,
157      {
158          self
159      }
160
161      // into_arc: Fn trait 需要 Send + Sync
162      #[inline]
163      fn into_arc(self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
164      where
165          Self: Sized + Send + Sync + 'static,
166      {
167          paste::paste! { [<Arc $trait_name>]::new(self) }
168      }
169
170      // ===== to_* 方法:克隆版本 =====
171
172      #[inline]
173      fn to_box(&self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
174      where
175          Self: Clone + Sized + 'static,
176      {
177          paste::paste! { [<Box $trait_name>]::new(self.clone()) }
178      }
179
180      #[inline]
181      fn to_rc(&self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
182      where
183          Self: Clone + Sized + 'static,
184      {
185          paste::paste! { [<Rc $trait_name>]::new(self.clone()) }
186      }
187
188      #[inline]
189      fn to_fn(&self) -> impl $closure_trait
190      where
191          Self: Clone + Sized + 'static,
192      {
193          self.clone()
194      }
195
196      // to_arc: Fn trait 需要 Send + Sync
197      #[inline]
198      fn to_arc(&self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
199      where
200          Self: Clone + Sized + Send + Sync + 'static,
201      {
202          paste::paste! { [<Arc $trait_name>]::new(self.clone()) }
203      }
204  };
205
206  // ==================== 内部实现:通用部分(FnMut trait)====================
207
208  (
209      @impl_common_fnmut
210      $trait_name:ident < $($generics:ident),* >,
211      $method_name:ident,
212      $closure_trait:path,
213      ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
214  ) => {
215      // 核心方法:直接调用闭包
216      #[inline]
217      fn $method_name(&mut self, $($arg: $arg_ty),*) $(-> $ret)? {
218          self($($arg),*)
219      }
220
221      // ===== 转换方法:使用 paste 自动推导类型名 =====
222
223      #[inline]
224      fn into_box(self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
225      where
226          Self: Sized + 'static,
227      {
228          paste::paste! { [<Box $trait_name>]::new(self) }
229      }
230
231      #[inline]
232      fn into_rc(self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
233      where
234          Self: Sized + 'static,
235      {
236          paste::paste! { [<Rc $trait_name>]::new(self) }
237      }
238
239      #[inline]
240      fn into_fn(self) -> impl $closure_trait
241      where
242          Self: Sized + 'static,
243      {
244          self
245      }
246
247      // into_arc: FnMut trait 只需要 Send
248      #[inline]
249      fn into_arc(self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
250      where
251          Self: Sized + Send + 'static,
252      {
253          paste::paste! { [<Arc $trait_name>]::new(self) }
254      }
255
256      // ===== to_* 方法:克隆版本 =====
257
258      #[inline]
259      fn to_box(&self) -> paste::paste! { [<Box $trait_name>] < $($generics),* > }
260      where
261          Self: Clone + Sized + 'static,
262      {
263          paste::paste! { [<Box $trait_name>]::new(self.clone()) }
264      }
265
266      #[inline]
267      fn to_rc(&self) -> paste::paste! { [<Rc $trait_name>] < $($generics),* > }
268      where
269          Self: Clone + Sized + 'static,
270      {
271          paste::paste! { [<Rc $trait_name>]::new(self.clone()) }
272      }
273
274      #[inline]
275      fn to_fn(&self) -> impl $closure_trait
276      where
277          Self: Clone + Sized + 'static,
278      {
279          self.clone()
280      }
281
282      // to_arc: FnMut trait 只需要 Send
283      #[inline]
284      fn to_arc(&self) -> paste::paste! { [<Arc $trait_name>] < $($generics),* > }
285      where
286          Self: Clone + Sized + Send + 'static,
287      {
288          let cloned = self.clone();
289          paste::paste! { [<Arc $trait_name>]::new(cloned) }
290      }
291  };
292
293
294  // ==================== 公共接口:参考 impl_rc_conversions 的模式 ====================
295
296  // Regular trait (Fn) - with once conversion
297  (
298      $trait_name:ident < $($generics:ident),* >,
299      $method_name:ident,
300      $once_type:ident,
301      Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
302  ) => {
303      impl<$($generics,)* F> $trait_name<$($generics),*> for F
304      where
305          F: Fn($($arg_ty),*) $(-> $ret)?,
306      {
307          // 生成通用方法
308          impl_closure_trait!(
309              @impl_common_fn
310              $trait_name<$($generics),*>,
311              $method_name,
312              Fn($($arg_ty),*) $(-> $ret)?,
313              ($($arg : $arg_ty),*) $(-> $ret)?
314          );
315
316          // 生成 into_once 和 to_once 方法
317          impl_closure_trait!(@into_once_fn_method $once_type, ($($generics),*));
318          impl_closure_trait!(@to_once_fn_method $once_type, ($($generics),*));
319      }
320  };
321
322  // Regular trait (Fn) - without once version
323  (
324      $trait_name:ident < $($generics:ident),* >,
325      $method_name:ident,
326      Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
327  ) => {
328      impl<$($generics,)* F> $trait_name<$($generics),*> for F
329      where
330          F: Fn($($arg_ty),*) $(-> $ret)?,
331      {
332          // 生成通用方法(不包含 into_once/to_once)
333          impl_closure_trait!(
334              @impl_common_fn
335              $trait_name<$($generics),*>,
336              $method_name,
337              Fn($($arg_ty),*) $(-> $ret)?,
338              ($($arg : $arg_ty),*) $(-> $ret)?
339          );
340      }
341  };
342
343  // Stateful trait (FnMut) - with once conversion
344  (
345      $trait_name:ident < $($generics:ident),* >,
346      $method_name:ident,
347      $once_type:ident,
348      FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
349  ) => {
350      impl<$($generics,)* F> $trait_name<$($generics),*> for F
351      where
352          F: FnMut($($arg_ty),*) $(-> $ret)?,
353      {
354          // 生成通用方法
355          impl_closure_trait!(
356              @impl_common_fnmut
357              $trait_name<$($generics),*>,
358              $method_name,
359              FnMut($($arg_ty),*) $(-> $ret)?,
360              ($($arg : $arg_ty),*) $(-> $ret)?
361          );
362
363          // 生成 into_once 和 to_once 方法
364          impl_closure_trait!(@into_once_fnmut_method $once_type, ($($generics),*), ($($arg : $arg_ty),*) $(-> $ret)?);
365          impl_closure_trait!(@to_once_fnmut_method $once_type, ($($generics),*), ($($arg : $arg_ty),*) $(-> $ret)?);
366      }
367  };
368
369  // Stateful trait (FnMut) - without once version
370  (
371      $trait_name:ident < $($generics:ident),* >,
372      $method_name:ident,
373      FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
374  ) => {
375      impl<$($generics,)* F> $trait_name<$($generics),*> for F
376      where
377          F: FnMut($($arg_ty),*) $(-> $ret)?,
378      {
379          // 生成通用方法(不包含 into_once/to_once)
380          impl_closure_trait!(
381              @impl_common_fnmut
382              $trait_name<$($generics),*>,
383              $method_name,
384              FnMut($($arg_ty),*) $(-> $ret)?,
385              ($($arg : $arg_ty),*) $(-> $ret)?
386          );
387      }
388  };
389}
390
391pub(crate) use impl_closure_trait;