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 fn into_box(self) -> $box_type<$($generics),*>
118 where
119 $($generics: 'static),*
120 {
121 $box_type::new_with_optional_name(
122 impl_arc_conversions!(@make_closure $call_mode, self.function,
123 $($arg),*),
124 self.name
125 )
126 }
127 };
128
129 // Helper: Generate a single conversion method (consuming self) - to Rc
130 (
131 @method_into_rc
132 $arc_type:ident < $($generics:ident),* >,
133 $rc_type:ident,
134 $call_mode:ident,
135 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
136 ) => {
137 fn into_rc(self) -> $rc_type<$($generics),*>
138 where
139 $($generics: 'static),*
140 {
141 $rc_type::new_with_optional_name(
142 impl_arc_conversions!(@make_closure $call_mode, self.function,
143 $($arg),*),
144 self.name
145 )
146 }
147 };
148
149 // Helper: Generate a single conversion method (consuming self) - to Once
150 (
151 @method_into_once
152 $arc_type:ident < $($generics:ident),* >,
153 $once_type:ident,
154 $call_mode:ident,
155 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
156 ) => {
157 fn into_once(self) -> $once_type<$($generics),*>
158 where
159 $($generics: 'static),*
160 {
161 $once_type::new_with_optional_name(
162 impl_arc_conversions!(@make_closure $call_mode, self.function,
163 $($arg),*),
164 self.name
165 )
166 }
167 };
168
169 // Helper: Generate a single conversion method (borrowing &self) - to Box
170 (
171 @method_to_box
172 $arc_type:ident < $($generics:ident),* >,
173 $box_type:ident,
174 $call_mode:ident,
175 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
176 ) => {
177 fn to_box(&self) -> $box_type<$($generics),*>
178 where
179 $($generics: 'static),*
180 {
181 let self_fn = self.function.clone();
182 let self_name = self.name.clone();
183 $box_type::new_with_optional_name(
184 impl_arc_conversions!(@make_closure $call_mode, self_fn,
185 $($arg),*),
186 self_name
187 )
188 }
189 };
190
191 // Helper: Generate a single conversion method (borrowing &self) - to Rc
192 (
193 @method_to_rc
194 $arc_type:ident < $($generics:ident),* >,
195 $rc_type:ident,
196 $call_mode:ident,
197 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
198 ) => {
199 fn to_rc(&self) -> $rc_type<$($generics),*>
200 where
201 $($generics: 'static),*
202 {
203 let self_fn = self.function.clone();
204 let self_name = self.name.clone();
205 $rc_type::new_with_optional_name(
206 impl_arc_conversions!(@make_closure $call_mode, self_fn,
207 $($arg),*),
208 self_name
209 )
210 }
211 };
212
213 // Helper: Generate a single conversion method (borrowing &self) - to Once
214 (
215 @method_to_once
216 $arc_type:ident < $($generics:ident),* >,
217 $once_type:ident,
218 $call_mode:ident,
219 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
220 ) => {
221 fn to_once(&self) -> $once_type<$($generics),*>
222 where
223 $($generics: 'static),*
224 {
225 let self_fn = self.function.clone();
226 let self_name = self.name.clone();
227 $once_type::new_with_optional_name(
228 impl_arc_conversions!(@make_closure $call_mode, self_fn,
229 $($arg),*),
230 self_name
231 )
232 }
233 };
234
235 // Helper: Generate into_fn method (consuming self, no return type, direct)
236 (
237 @fn_method_into
238 direct,
239 ($($arg:ident : $arg_ty:ty),*)
240 ) => {
241 fn into_fn(self) -> impl Fn($($arg_ty),*)
242 {
243 move |$($arg),*| (self.function)($($arg),*)
244 }
245 };
246
247 // Helper: Generate into_fn method (consuming self, with return type, direct)
248 (
249 @fn_method_into
250 direct,
251 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
252 ) => {
253 fn into_fn(self) -> impl Fn($($arg_ty),*) -> $ret
254 {
255 move |$($arg),*| (self.function)($($arg),*)
256 }
257 };
258
259 // Helper: Generate into_fn method (consuming self, no return type, lock_unwrap)
260 (
261 @fn_method_into
262 lock_unwrap,
263 ($($arg:ident : $arg_ty:ty),*)
264 ) => {
265 fn into_fn(self) -> impl FnMut($($arg_ty),*)
266 {
267 move |$($arg),*| (self.function.lock())($($arg),*)
268 }
269 };
270
271 // Helper: Generate into_fn method (consuming self, with return type,
272 // lock_unwrap)
273 (
274 @fn_method_into
275 lock_unwrap,
276 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
277 ) => {
278 fn into_fn(self) -> impl FnMut($($arg_ty),*) -> $ret
279 {
280 move |$($arg),*| (self.function.lock())($($arg),*)
281 }
282 };
283
284 // Helper: Generate to_fn method (borrowing &self, no return type, direct)
285 (
286 @fn_method_to
287 direct,
288 ($($arg:ident : $arg_ty:ty),*)
289 ) => {
290 fn to_fn(&self) -> impl Fn($($arg_ty),*)
291 {
292 let self_fn = self.function.clone();
293 move |$($arg),*| (self_fn)($($arg),*)
294 }
295 };
296
297 // Helper: Generate to_fn method (borrowing &self, with return type, direct)
298 (
299 @fn_method_to
300 direct,
301 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
302 ) => {
303 fn to_fn(&self) -> impl Fn($($arg_ty),*) -> $ret
304 {
305 let self_fn = self.function.clone();
306 move |$($arg),*| (self_fn)($($arg),*)
307 }
308 };
309
310 // Helper: Generate to_fn method (borrowing &self, no return type, lock_unwrap)
311 (
312 @fn_method_to
313 lock_unwrap,
314 ($($arg:ident : $arg_ty:ty),*)
315 ) => {
316 fn to_fn(&self) -> impl FnMut($($arg_ty),*)
317 {
318 let self_fn = self.function.clone();
319 move |$($arg),*| (self_fn.lock())($($arg),*)
320 }
321 };
322
323 // Helper: Generate to_fn method (borrowing &self, with return type,
324 // lock_unwrap)
325 (
326 @fn_method_to
327 lock_unwrap,
328 ($($arg:ident : $arg_ty:ty),*) -> $ret:ty
329 ) => {
330 fn to_fn(&self) -> impl FnMut($($arg_ty),*) -> $ret
331 {
332 let self_fn = self.function.clone();
333 move |$($arg),*| (self_fn.lock())($($arg),*)
334 }
335 };
336
337 // Helper: Make closure based on call mode
338 (@make_closure direct, $fn_call:expr, $($arg:ident),*) => {
339 move |$($arg),*| ($fn_call)($($arg),*)
340 };
341 (@make_closure lock_unwrap, $fn_call:expr, $($arg:ident),*) => {
342 move |$($arg),*| ($fn_call.lock())($($arg),*)
343 };
344
345 // ==================== Main Implementation ====================
346
347 // Internal implementation: Generate all methods
348 (
349 @impl
350 $arc_type:ident < $($generics:ident),* >,
351 $box_type:ident,
352 $rc_type:ident,
353 $once_type:ident,
354 $call_mode:ident,
355 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
356 ) => {
357 // into_box: consumes self, returns Box
358 impl_arc_conversions!(
359 @method_into_box
360 $arc_type<$($generics),*>, $box_type,
361 $call_mode,
362 ($($arg : $arg_ty),*) $(-> $ret)?
363 );
364
365 // into_rc: consumes self, returns Rc
366 impl_arc_conversions!(
367 @method_into_rc
368 $arc_type<$($generics),*>, $rc_type,
369 $call_mode,
370 ($($arg : $arg_ty),*) $(-> $ret)?
371 );
372
373 // into_arc: consumes self, returns self (zero-cost)
374 fn into_arc(self) -> $arc_type<$($generics),*>
375 where
376 $($generics: 'static),*
377 {
378 self
379 }
380
381 // into_fn: consumes self, returns impl Fn/FnMut
382 impl_arc_conversions!(
383 @fn_method_into
384 $call_mode,
385 ($($arg : $arg_ty),*) $(-> $ret)?
386 );
387
388 // into_once: consumes self, returns Once
389 impl_arc_conversions!(
390 @method_into_once
391 $arc_type<$($generics),*>, $once_type,
392 $call_mode,
393 ($($arg : $arg_ty),*) $(-> $ret)?
394 );
395
396 // to_box: borrows self, clones and returns Box
397 impl_arc_conversions!(
398 @method_to_box
399 $arc_type<$($generics),*>, $box_type,
400 $call_mode,
401 ($($arg : $arg_ty),*) $(-> $ret)?
402 );
403
404 // to_rc: borrows self, clones and returns Rc
405 impl_arc_conversions!(
406 @method_to_rc
407 $arc_type<$($generics),*>, $rc_type,
408 $call_mode,
409 ($($arg : $arg_ty),*) $(-> $ret)?
410 );
411
412 // to_arc: borrows self, returns clone (cheap Arc clone)
413 fn to_arc(&self) -> $arc_type<$($generics),*>
414 where
415 $($generics: 'static),*
416 {
417 self.clone()
418 }
419
420 // to_fn: borrows self, clones and returns impl Fn/FnMut
421 impl_arc_conversions!(
422 @fn_method_to
423 $call_mode,
424 ($($arg : $arg_ty),*) $(-> $ret)?
425 );
426
427 // to_once: borrows self, clones and returns Once
428 impl_arc_conversions!(
429 @method_to_once
430 $arc_type<$($generics),*>, $once_type,
431 $call_mode,
432 ($($arg : $arg_ty),*) $(-> $ret)?
433 );
434 };
435
436 // Internal implementation: Generate methods without once type
437 (
438 @impl_no_once
439 $arc_type:ident < $($generics:ident),* >,
440 $box_type:ident,
441 $rc_type:ident,
442 $call_mode:ident,
443 ($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
444 ) => {
445 // into_box: consumes self, returns Box
446 impl_arc_conversions!(
447 @method_into_box
448 $arc_type<$($generics),*>, $box_type,
449 $call_mode,
450 ($($arg : $arg_ty),*) $(-> $ret)?
451 );
452
453 // into_rc: consumes self, returns Rc
454 impl_arc_conversions!(
455 @method_into_rc
456 $arc_type<$($generics),*>, $rc_type,
457 $call_mode,
458 ($($arg : $arg_ty),*) $(-> $ret)?
459 );
460
461 // into_arc: consumes self, returns self (zero-cost)
462 fn into_arc(self) -> $arc_type<$($generics),*>
463 where
464 $($generics: 'static),*
465 {
466 self
467 }
468
469 // into_fn: consumes self, returns impl Fn/FnMut
470 impl_arc_conversions!(
471 @fn_method_into
472 $call_mode,
473 ($($arg : $arg_ty),*) $(-> $ret)?
474 );
475
476 // to_box: borrows self, clones and returns Box
477 impl_arc_conversions!(
478 @method_to_box
479 $arc_type<$($generics),*>, $box_type,
480 $call_mode,
481 ($($arg : $arg_ty),*) $(-> $ret)?
482 );
483
484 // to_rc: borrows self, clones and returns Rc
485 impl_arc_conversions!(
486 @method_to_rc
487 $arc_type<$($generics),*>, $rc_type,
488 $call_mode,
489 ($($arg : $arg_ty),*) $(-> $ret)?
490 );
491
492 // to_arc: borrows self, returns clone (cheap Arc clone)
493 fn to_arc(&self) -> $arc_type<$($generics),*>
494 where
495 $($generics: 'static),*
496 {
497 self.clone()
498 }
499
500 // to_fn: borrows self, clones and returns impl Fn/FnMut
501 impl_arc_conversions!(
502 @fn_method_to
503 $call_mode,
504 ($($arg : $arg_ty),*) $(-> $ret)?
505 );
506 };
507
508 // ==================== Public Interface ====================
509
510 // Fn(...) → direct call mode (immutable, no interior mutability)
511 (
512 $arc_type:ident < $($generics:ident),* >,
513 $box_type:ident,
514 $rc_type:ident,
515 $once_type:ident,
516 Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
517 ) => {
518 impl_arc_conversions!(
519 @impl
520 $arc_type<$($generics),*>,
521 $box_type,
522 $rc_type,
523 $once_type,
524 direct,
525 ($($arg : $arg_ty),*) $(-> $ret)?
526 );
527 };
528
529 // FnMut(...) → lock_unwrap call mode (mutable, needs Mutex)
530 (
531 $arc_type:ident < $($generics:ident),* >,
532 $box_type:ident,
533 $rc_type:ident,
534 $once_type:ident,
535 FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
536 ) => {
537 impl_arc_conversions!(
538 @impl
539 $arc_type<$($generics),*>,
540 $box_type,
541 $rc_type,
542 $once_type,
543 lock_unwrap,
544 ($($arg : $arg_ty),*) $(-> $ret)?
545 );
546 };
547
548 // Fn(...) → direct call mode (immutable, no interior mutability) - no once type
549 (
550 $arc_type:ident < $($generics:ident),* >,
551 $box_type:ident,
552 $rc_type:ident,
553 Fn($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
554 ) => {
555 impl_arc_conversions!(
556 @impl_no_once
557 $arc_type<$($generics),*>,
558 $box_type,
559 $rc_type,
560 direct,
561 ($($arg : $arg_ty),*) $(-> $ret)?
562 );
563 };
564
565 // FnMut(...) → lock_unwrap call mode (mutable, needs Mutex) - no once type
566 (
567 $arc_type:ident < $($generics:ident),* >,
568 $box_type:ident,
569 $rc_type:ident,
570 FnMut($($arg:ident : $arg_ty:ty),*) $(-> $ret:ty)?
571 ) => {
572 impl_arc_conversions!(
573 @impl_no_once
574 $arc_type<$($generics),*>,
575 $box_type,
576 $rc_type,
577 lock_unwrap,
578 ($($arg : $arg_ty),*) $(-> $ret)?
579 );
580 };
581}
582
583pub(crate) use impl_arc_conversions;