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 where
391 $($generics: 'static),*
392 {
393 self
394 }
395
396 // into_fn: consumes self, returns impl Fn/FnMut
397 impl_arc_conversions!(
398 @fn_method_into
399 $call_mode,
400 ($($arg : $arg_ty),*) $(-> $ret)?
401 );
402
403 // into_once: consumes self, returns Once
404 impl_arc_conversions!(
405 @method_into_once
406 $arc_type<$($generics),*>, $once_type,
407 $call_mode,
408 ($($arg : $arg_ty),*) $(-> $ret)?
409 );
410
411 // to_box: borrows self, clones and returns Box
412 impl_arc_conversions!(
413 @method_to_box
414 $arc_type<$($generics),*>, $box_type,
415 $call_mode,
416 ($($arg : $arg_ty),*) $(-> $ret)?
417 );
418
419 // to_rc: borrows self, clones and returns Rc
420 impl_arc_conversions!(
421 @method_to_rc
422 $arc_type<$($generics),*>, $rc_type,
423 $call_mode,
424 ($($arg : $arg_ty),*) $(-> $ret)?
425 );
426
427 // to_arc: borrows self, returns clone (cheap Arc clone)
428 #[inline]
429 fn to_arc(&self) -> $arc_type<$($generics),*>
430 where
431 $($generics: 'static),*
432 {
433 self.clone()
434 }
435
436 // to_fn: borrows self, clones and returns impl Fn/FnMut
437 impl_arc_conversions!(
438 @fn_method_to
439 $call_mode,
440 ($($arg : $arg_ty),*) $(-> $ret)?
441 );
442
443 // to_once: borrows self, clones and returns Once
444 impl_arc_conversions!(
445 @method_to_once
446 $arc_type<$($generics),*>, $once_type,
447 $call_mode,
448 ($($arg : $arg_ty),*) $(-> $ret)?
449 );
450 };
451
452 // Internal implementation: Generate methods without once type
453 (
454 @impl_no_once
455 $arc_type:ident < $($generics:ident),* >,
456 $box_type:ident,
457 $rc_type:ident,
458 $call_mode:ident,
459 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
460 ) => {
461 // into_box: consumes self, returns Box
462 impl_arc_conversions!(
463 @method_into_box
464 $arc_type<$($generics),*>, $box_type,
465 $call_mode,
466 ($($arg : $arg_ty),*) $(-> $ret)?
467 );
468
469 // into_rc: consumes self, returns Rc
470 impl_arc_conversions!(
471 @method_into_rc
472 $arc_type<$($generics),*>, $rc_type,
473 $call_mode,
474 ($($arg : $arg_ty),*) $(-> $ret)?
475 );
476
477 // into_arc: consumes self, returns self (zero-cost)
478 #[inline]
479 fn into_arc(self) -> $arc_type<$($generics),*>
480 where
481 $($generics: 'static),*
482 {
483 self
484 }
485
486 // into_fn: consumes self, returns impl Fn/FnMut
487 impl_arc_conversions!(
488 @fn_method_into
489 $call_mode,
490 ($($arg : $arg_ty),*) $(-> $ret)?
491 );
492
493 // to_box: borrows self, clones and returns Box
494 impl_arc_conversions!(
495 @method_to_box
496 $arc_type<$($generics),*>, $box_type,
497 $call_mode,
498 ($($arg : $arg_ty),*) $(-> $ret)?
499 );
500
501 // to_rc: borrows self, clones and returns Rc
502 impl_arc_conversions!(
503 @method_to_rc
504 $arc_type<$($generics),*>, $rc_type,
505 $call_mode,
506 ($($arg : $arg_ty),*) $(-> $ret)?
507 );
508
509 // to_arc: borrows self, returns clone (cheap Arc clone)
510 #[inline]
511 fn to_arc(&self) -> $arc_type<$($generics),*>
512 where
513 $($generics: 'static),*
514 {
515 self.clone()
516 }
517
518 // to_fn: borrows self, clones and returns impl Fn/FnMut
519 impl_arc_conversions!(
520 @fn_method_to
521 $call_mode,
522 ($($arg : $arg_ty),*) $(-> $ret)?
523 );
524 };
525
526 // ==================== Public Interface ====================
527
528 // Fn(...) → direct call mode (immutable, no interior mutability)
529 (
530 $arc_type:ident < $($generics:ident),* >,
531 $box_type:ident,
532 $rc_type:ident,
533 $once_type:ident,
534 Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
535 ) => {
536 impl_arc_conversions!(
537 @impl
538 $arc_type<$($generics),*>,
539 $box_type,
540 $rc_type,
541 $once_type,
542 direct,
543 ($($arg : $arg_ty),*) $(-> $ret)?
544 );
545 };
546
547 // FnMut(...) → lock_unwrap call mode (mutable, needs Mutex)
548 (
549 $arc_type:ident < $($generics:ident),* >,
550 $box_type:ident,
551 $rc_type:ident,
552 $once_type:ident,
553 FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
554 ) => {
555 impl_arc_conversions!(
556 @impl
557 $arc_type<$($generics),*>,
558 $box_type,
559 $rc_type,
560 $once_type,
561 lock_unwrap,
562 ($($arg : $arg_ty),*) $(-> $ret)?
563 );
564 };
565
566 // Fn(...) → direct call mode (immutable, no interior mutability) - no once type
567 (
568 $arc_type:ident < $($generics:ident),* >,
569 $box_type:ident,
570 $rc_type:ident,
571 Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
572 ) => {
573 impl_arc_conversions!(
574 @impl_no_once
575 $arc_type<$($generics),*>,
576 $box_type,
577 $rc_type,
578 direct,
579 ($($arg : $arg_ty),*) $(-> $ret)?
580 );
581 };
582
583 // FnMut(...) → lock_unwrap call mode (mutable, needs Mutex) - no once type
584 (
585 $arc_type:ident < $($generics:ident),* >,
586 $box_type:ident,
587 $rc_type:ident,
588 FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
589 ) => {
590 impl_arc_conversions!(
591 @impl_no_once
592 $arc_type<$($generics),*>,
593 $box_type,
594 $rc_type,
595 lock_unwrap,
596 ($($arg : $arg_ty),*) $(-> $ret)?
597 );
598 };
599}
600
601pub(crate) use impl_arc_conversions;