qubit_function/macros/arc_conversions.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9
10////////////////////////////////////////////////////////////////////////////////
11//
12/*
13 * Copyright (c) 2025 - 2026.
14 * Haixing Hu, Qubit Co. Ltd.
15 *
16 * All rights reserved.
17 *
18 */
19
20////////////////////////////////////////////////////////////////////////////////
21
22//! # Arc Conversions Macro
23//!
24//! Generates common into_xxx() conversion methods for all Arc-based function
25//! wrappers.
26//!
27//! This macro automatically infers everything from the function signature:
28//! - Number of parameters
29//! - Parameter types
30//! - Return type
31//! - Call mode (Fn → direct, FnMut → lock_unwrap)
32//!
33//! # Author
34//!
35//! Haixing Hu
36
37/// Public interface macro for Arc-based conversions.
38///
39/// This macro automatically infers everything from the function signature:
40/// - Number of parameters
41/// - Parameter types
42/// - Return type
43/// - Call mode (Fn → direct, FnMut → lock_unwrap)
44///
45/// # Syntax
46///
47/// ```ignore
48/// // 4-parameter version (with once type, for consumers, functions, etc.)
49/// impl_arc_conversions!(
50/// ArcType<Generics>, // Arc wrapper type with all generic params
51/// BoxType, // Corresponding Box wrapper type
52/// RcType, // Corresponding Rc wrapper type
53/// OnceType, // Corresponding once wrapper type
54/// Fn(args) [-> RetType] // Fn or FnMut signature (auto-infers everything!)
55/// );
56///
57/// // 3-parameter version (no once type, for predicates and similar pure functions)
58/// impl_arc_conversions!(
59/// ArcType<Generics>, // Arc wrapper type with all generic params
60/// BoxType, // Corresponding Box wrapper type
61/// RcType, // Corresponding Rc wrapper type
62/// Fn(args) [-> RetType] // Fn or FnMut signature (auto-infers everything!)
63/// );
64/// ```
65///
66/// # Examples
67///
68/// ```ignore
69/// // Predicate: Fn(&T) -> bool → direct call mode (no once type)
70/// impl_arc_conversions!(ArcPredicate<T>, BoxPredicate, RcPredicate,
71/// Fn(t: &T) -> bool);
72///
73/// // BiPredicate: Fn(&T, &U) -> bool → direct call mode (no once type)
74/// impl_arc_conversions!(ArcBiPredicate<T, U>, BoxBiPredicate, RcBiPredicate,
75/// Fn(t: &T, u: &U) -> bool);
76///
77/// // Consumer: Fn(&T) → direct call mode (with once type)
78/// impl_arc_conversions!(ArcConsumer<T>, BoxConsumer, RcConsumer,
79/// BoxConsumerOnce, Fn(t: &T));
80///
81/// // StatefulConsumer: FnMut(&T) → lock_unwrap call mode (with once type)
82/// impl_arc_conversions!(ArcStatefulConsumer<T>, BoxStatefulConsumer,
83/// RcStatefulConsumer, BoxConsumerOnce, FnMut(t: &T));
84///
85/// // BiConsumer: Fn(&T, &U) → direct call mode (with once type)
86/// impl_arc_conversions!(ArcBiConsumer<T, U>, BoxBiConsumer, RcBiConsumer,
87/// BoxBiConsumerOnce, Fn(t: &T, u: &U));
88///
89/// // Function: Fn(&T) -> R → direct call mode (with once type)
90/// impl_arc_conversions!(ArcFunction<T, R>, BoxFunction, RcFunction,
91/// BoxFunctionOnce, Fn(t: &T) -> R);
92///
93/// // StatefulFunction: FnMut(&T) -> R → lock_unwrap call mode (with once type)
94/// impl_arc_conversions!(ArcStatefulFunction<T, R>, BoxStatefulFunction,
95/// RcStatefulFunction, BoxFunctionOnce, FnMut(t: &T) -> R);
96///
97/// // MutatingFunction: Fn(&mut T) -> R → direct call mode (with once type)
98/// impl_arc_conversions!(ArcMutatingFunction<T, R>, BoxMutatingFunction,
99/// RcMutatingFunction, BoxMutatingFunctionOnce,
100/// Fn(input: &mut T) -> R);
101/// ```
102///
103/// # Author
104///
105/// Haixing Hu
106macro_rules! impl_arc_conversions {
107 // ==================== Core Macro: Generate Single Method ====================
108
109 // Helper: Generate a single conversion method (consuming self) - to Box
110 (
111 @method_into_box
112 $arc_type:ident < $($generics:ident),* >,
113 $box_type:ident,
114 $call_mode:ident,
115 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
116 ) => {
117 #[inline]
118 fn into_box(self) -> $box_type<$($generics),*>
119 where
120 $($generics: 'static),*
121 {
122 $box_type::new_with_optional_name(
123 impl_arc_conversions!(@make_closure $call_mode, self.function,
124 $($arg),*),
125 self.name
126 )
127 }
128 };
129
130 // Helper: Generate a single conversion method (consuming self) - to Rc
131 (
132 @method_into_rc
133 $arc_type:ident < $($generics:ident),* >,
134 $rc_type:ident,
135 $call_mode:ident,
136 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
137 ) => {
138 #[inline]
139 fn into_rc(self) -> $rc_type<$($generics),*>
140 where
141 $($generics: 'static),*
142 {
143 $rc_type::new_with_optional_name(
144 impl_arc_conversions!(@make_closure $call_mode, self.function,
145 $($arg),*),
146 self.name
147 )
148 }
149 };
150
151 // Helper: Generate a single conversion method (consuming self) - to Once
152 (
153 @method_into_once
154 $arc_type:ident < $($generics:ident),* >,
155 $once_type:ident,
156 $call_mode:ident,
157 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
158 ) => {
159 #[inline]
160 fn into_once(self) -> $once_type<$($generics),*>
161 where
162 $($generics: 'static),*
163 {
164 $once_type::new_with_optional_name(
165 impl_arc_conversions!(@make_closure $call_mode, self.function,
166 $($arg),*),
167 self.name
168 )
169 }
170 };
171
172 // Helper: Generate a single conversion method (borrowing &self) - to Box
173 (
174 @method_to_box
175 $arc_type:ident < $($generics:ident),* >,
176 $box_type:ident,
177 $call_mode:ident,
178 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
179 ) => {
180 #[inline]
181 fn to_box(&self) -> $box_type<$($generics),*>
182 where
183 $($generics: 'static),*
184 {
185 let self_fn = self.function.clone();
186 let self_name = self.name.clone();
187 $box_type::new_with_optional_name(
188 impl_arc_conversions!(@make_closure $call_mode, self_fn,
189 $($arg),*),
190 self_name
191 )
192 }
193 };
194
195 // Helper: Generate a single conversion method (borrowing &self) - to Rc
196 (
197 @method_to_rc
198 $arc_type:ident < $($generics:ident),* >,
199 $rc_type:ident,
200 $call_mode:ident,
201 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
202 ) => {
203 #[inline]
204 fn to_rc(&self) -> $rc_type<$($generics),*>
205 where
206 $($generics: 'static),*
207 {
208 let self_fn = self.function.clone();
209 let self_name = self.name.clone();
210 $rc_type::new_with_optional_name(
211 impl_arc_conversions!(@make_closure $call_mode, self_fn,
212 $($arg),*),
213 self_name
214 )
215 }
216 };
217
218 // Helper: Generate a single conversion method (borrowing &self) - to Once
219 (
220 @method_to_once
221 $arc_type:ident < $($generics:ident),* >,
222 $once_type:ident,
223 $call_mode:ident,
224 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
225 ) => {
226 #[inline]
227 fn to_once(&self) -> $once_type<$($generics),*>
228 where
229 $($generics: 'static),*
230 {
231 let self_fn = self.function.clone();
232 let self_name = self.name.clone();
233 $once_type::new_with_optional_name(
234 impl_arc_conversions!(@make_closure $call_mode, self_fn,
235 $($arg),*),
236 self_name
237 )
238 }
239 };
240
241 // Helper: Generate into_fn method (consuming self, no return type, direct)
242 (
243 @fn_method_into
244 direct,
245 ($($arg:ident : $arg_ty:ty),*)
246 ) => {
247 #[inline]
248 fn into_fn(self) -> impl Fn($($arg_ty),*)
249 {
250 move |$($arg),*| (self.function)($($arg),*)
251 }
252 };
253
254 // Helper: Generate into_fn method (consuming self, with return type, direct)
255 (
256 @fn_method_into
257 direct,
258 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
259 ) => {
260 #[inline]
261 fn into_fn(self) -> impl Fn($($arg_ty),*) -> $ret
262 {
263 move |$($arg),*| (self.function)($($arg),*)
264 }
265 };
266
267 // Helper: Generate into_fn method (consuming self, no return type, lock_unwrap)
268 (
269 @fn_method_into
270 lock_unwrap,
271 ($($arg:ident : $arg_ty:ty),*)
272 ) => {
273 #[inline]
274 fn into_fn(self) -> impl FnMut($($arg_ty),*)
275 {
276 move |$($arg),*| (self.function.lock())($($arg),*)
277 }
278 };
279
280 // Helper: Generate into_fn method (consuming self, with return type,
281 // lock_unwrap)
282 (
283 @fn_method_into
284 lock_unwrap,
285 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
286 ) => {
287 #[inline]
288 fn into_fn(self) -> impl FnMut($($arg_ty),*) -> $ret
289 {
290 move |$($arg),*| (self.function.lock())($($arg),*)
291 }
292 };
293
294 // Helper: Generate to_fn method (borrowing &self, no return type, direct)
295 (
296 @fn_method_to
297 direct,
298 ($($arg:ident : $arg_ty:ty),*)
299 ) => {
300 #[inline]
301 fn to_fn(&self) -> impl Fn($($arg_ty),*)
302 {
303 let self_fn = self.function.clone();
304 move |$($arg),*| (self_fn)($($arg),*)
305 }
306 };
307
308 // Helper: Generate to_fn method (borrowing &self, with return type, direct)
309 (
310 @fn_method_to
311 direct,
312 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
313 ) => {
314 #[inline]
315 fn to_fn(&self) -> impl Fn($($arg_ty),*) -> $ret
316 {
317 let self_fn = self.function.clone();
318 move |$($arg),*| (self_fn)($($arg),*)
319 }
320 };
321
322 // Helper: Generate to_fn method (borrowing &self, no return type, lock_unwrap)
323 (
324 @fn_method_to
325 lock_unwrap,
326 ($($arg:ident : $arg_ty:ty),*)
327 ) => {
328 #[inline]
329 fn to_fn(&self) -> impl FnMut($($arg_ty),*)
330 {
331 let self_fn = self.function.clone();
332 move |$($arg),*| (self_fn.lock())($($arg),*)
333 }
334 };
335
336 // Helper: Generate to_fn method (borrowing &self, with return type,
337 // lock_unwrap)
338 (
339 @fn_method_to
340 lock_unwrap,
341 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
342 ) => {
343 #[inline]
344 fn to_fn(&self) -> impl FnMut($($arg_ty),*) -> $ret
345 {
346 let self_fn = self.function.clone();
347 move |$($arg),*| (self_fn.lock())($($arg),*)
348 }
349 };
350
351 // Helper: Make closure based on call mode
352 (@make_closure direct, $fn_call:expr, $($arg:ident),*) => {
353 move |$($arg),*| ($fn_call)($($arg),*)
354 };
355 (@make_closure lock_unwrap, $fn_call:expr, $($arg:ident),*) => {
356 move |$($arg),*| ($fn_call.lock())($($arg),*)
357 };
358
359 // ==================== Main Implementation ====================
360
361 // Internal implementation: Generate all methods
362 (
363 @impl
364 $arc_type:ident < $($generics:ident),* >,
365 $box_type:ident,
366 $rc_type:ident,
367 $once_type:ident,
368 $call_mode:ident,
369 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
370 ) => {
371 // into_box: consumes self, returns Box
372 impl_arc_conversions!(
373 @method_into_box
374 $arc_type<$($generics),*>, $box_type,
375 $call_mode,
376 ($($arg : $arg_ty),*) $(-> $ret)?
377 );
378
379 // into_rc: consumes self, returns Rc
380 impl_arc_conversions!(
381 @method_into_rc
382 $arc_type<$($generics),*>, $rc_type,
383 $call_mode,
384 ($($arg : $arg_ty),*) $(-> $ret)?
385 );
386
387 // into_arc: consumes self, returns self (zero-cost)
388 #[inline]
389 fn into_arc(self) -> $arc_type<$($generics),*>
390 {
391 self
392 }
393
394 // into_fn: consumes self, returns impl Fn/FnMut
395 impl_arc_conversions!(
396 @fn_method_into
397 $call_mode,
398 ($($arg : $arg_ty),*) $(-> $ret)?
399 );
400
401 // into_once: consumes self, returns Once
402 impl_arc_conversions!(
403 @method_into_once
404 $arc_type<$($generics),*>, $once_type,
405 $call_mode,
406 ($($arg : $arg_ty),*) $(-> $ret)?
407 );
408
409 // to_box: borrows self, clones and returns Box
410 impl_arc_conversions!(
411 @method_to_box
412 $arc_type<$($generics),*>, $box_type,
413 $call_mode,
414 ($($arg : $arg_ty),*) $(-> $ret)?
415 );
416
417 // to_rc: borrows self, clones and returns Rc
418 impl_arc_conversions!(
419 @method_to_rc
420 $arc_type<$($generics),*>, $rc_type,
421 $call_mode,
422 ($($arg : $arg_ty),*) $(-> $ret)?
423 );
424
425 // to_arc: borrows self, returns clone (cheap Arc clone)
426 #[inline]
427 fn to_arc(&self) -> $arc_type<$($generics),*>
428 {
429 self.clone()
430 }
431
432 // to_fn: borrows self, clones and returns impl Fn/FnMut
433 impl_arc_conversions!(
434 @fn_method_to
435 $call_mode,
436 ($($arg : $arg_ty),*) $(-> $ret)?
437 );
438
439 // to_once: borrows self, clones and returns Once
440 impl_arc_conversions!(
441 @method_to_once
442 $arc_type<$($generics),*>, $once_type,
443 $call_mode,
444 ($($arg : $arg_ty),*) $(-> $ret)?
445 );
446 };
447
448 // Internal implementation: Generate methods without once type
449 (
450 @impl_no_once
451 $arc_type:ident < $($generics:ident),* >,
452 $box_type:ident,
453 $rc_type:ident,
454 $call_mode:ident,
455 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
456 ) => {
457 // into_box: consumes self, returns Box
458 impl_arc_conversions!(
459 @method_into_box
460 $arc_type<$($generics),*>, $box_type,
461 $call_mode,
462 ($($arg : $arg_ty),*) $(-> $ret)?
463 );
464
465 // into_rc: consumes self, returns Rc
466 impl_arc_conversions!(
467 @method_into_rc
468 $arc_type<$($generics),*>, $rc_type,
469 $call_mode,
470 ($($arg : $arg_ty),*) $(-> $ret)?
471 );
472
473 // into_arc: consumes self, returns self (zero-cost)
474 #[inline]
475 fn into_arc(self) -> $arc_type<$($generics),*>
476 {
477 self
478 }
479
480 // into_fn: consumes self, returns impl Fn/FnMut
481 impl_arc_conversions!(
482 @fn_method_into
483 $call_mode,
484 ($($arg : $arg_ty),*) $(-> $ret)?
485 );
486
487 // to_box: borrows self, clones and returns Box
488 impl_arc_conversions!(
489 @method_to_box
490 $arc_type<$($generics),*>, $box_type,
491 $call_mode,
492 ($($arg : $arg_ty),*) $(-> $ret)?
493 );
494
495 // to_rc: borrows self, clones and returns Rc
496 impl_arc_conversions!(
497 @method_to_rc
498 $arc_type<$($generics),*>, $rc_type,
499 $call_mode,
500 ($($arg : $arg_ty),*) $(-> $ret)?
501 );
502
503 // to_arc: borrows self, returns clone (cheap Arc clone)
504 #[inline]
505 fn to_arc(&self) -> $arc_type<$($generics),*>
506 {
507 self.clone()
508 }
509
510 // to_fn: borrows self, clones and returns impl Fn/FnMut
511 impl_arc_conversions!(
512 @fn_method_to
513 $call_mode,
514 ($($arg : $arg_ty),*) $(-> $ret)?
515 );
516 };
517
518 // ==================== Public Interface ====================
519
520 // Fn(...) → direct call mode (immutable, no interior mutability)
521 (
522 $arc_type:ident < $($generics:ident),* >,
523 $box_type:ident,
524 $rc_type:ident,
525 $once_type:ident,
526 Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
527 ) => {
528 impl_arc_conversions!(
529 @impl
530 $arc_type<$($generics),*>,
531 $box_type,
532 $rc_type,
533 $once_type,
534 direct,
535 ($($arg : $arg_ty),*) $(-> $ret)?
536 );
537 };
538
539 // FnMut(...) → lock_unwrap call mode (mutable, needs Mutex)
540 (
541 $arc_type:ident < $($generics:ident),* >,
542 $box_type:ident,
543 $rc_type:ident,
544 $once_type:ident,
545 FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
546 ) => {
547 impl_arc_conversions!(
548 @impl
549 $arc_type<$($generics),*>,
550 $box_type,
551 $rc_type,
552 $once_type,
553 lock_unwrap,
554 ($($arg : $arg_ty),*) $(-> $ret)?
555 );
556 };
557
558 // Fn(...) → direct call mode (immutable, no interior mutability) - no once type
559 (
560 $arc_type:ident < $($generics:ident),* >,
561 $box_type:ident,
562 $rc_type:ident,
563 Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
564 ) => {
565 impl_arc_conversions!(
566 @impl_no_once
567 $arc_type<$($generics),*>,
568 $box_type,
569 $rc_type,
570 direct,
571 ($($arg : $arg_ty),*) $(-> $ret)?
572 );
573 };
574
575 // FnMut(...) → lock_unwrap call mode (mutable, needs Mutex) - no once type
576 (
577 $arc_type:ident < $($generics:ident),* >,
578 $box_type:ident,
579 $rc_type:ident,
580 FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
581 ) => {
582 impl_arc_conversions!(
583 @impl_no_once
584 $arc_type<$($generics),*>,
585 $box_type,
586 $rc_type,
587 lock_unwrap,
588 ($($arg : $arg_ty),*) $(-> $ret)?
589 );
590 };
591}
592
593pub(crate) use impl_arc_conversions;