qubit_function/tasks/runnable/arc_runnable.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10// qubit-style: allow explicit-imports
11//! Defines the `ArcRunnable` public type.
12
13#![allow(unused_imports)]
14
15use super::*;
16
17// ============================================================================
18// ArcRunnable
19// ============================================================================
20
21/// Thread-safe runnable.
22///
23/// `ArcRunnable<E>` stores an `Arc<Mutex<dyn FnMut() -> Result<(), E> + Send>>`
24/// and can be called repeatedly across threads.
25///
26/// # Type Parameters
27///
28/// * `E` - The error value returned when the action fails.
29///
30pub struct ArcRunnable<E> {
31 /// The stateful closure executed by this runnable.
32 pub(super) function: Arc<Mutex<dyn FnMut() -> Result<(), E> + Send>>,
33 /// The optional name of this runnable.
34 pub(super) name: Option<String>,
35}
36
37impl<E> Clone for ArcRunnable<E> {
38 #[inline]
39 fn clone(&self) -> Self {
40 Self {
41 function: Arc::clone(&self.function),
42 name: self.name.clone(),
43 }
44 }
45}
46
47impl<E> ArcRunnable<E> {
48 impl_common_new_methods!(
49 (FnMut() -> Result<(), E> + Send + 'static),
50 |function| Arc::new(Mutex::new(function)),
51 "runnable"
52 );
53
54 /// Creates a thread-safe runnable from a reusable supplier.
55 ///
56 /// # Parameters
57 ///
58 /// * `supplier` - The supplier that produces the runnable result.
59 ///
60 /// # Returns
61 ///
62 /// A new `ArcRunnable<E>`.
63 #[inline]
64 pub fn from_supplier<S>(supplier: S) -> Self
65 where
66 S: Supplier<Result<(), E>> + Send + 'static,
67 {
68 Self::new(move || supplier.get())
69 }
70
71 impl_common_name_methods!("runnable");
72}
73
74impl<E> Runnable<E> for ArcRunnable<E> {
75 /// Executes the thread-safe runnable.
76 #[inline]
77 fn run(&mut self) -> Result<(), E> {
78 (self.function.lock())()
79 }
80
81 impl_arc_conversions!(
82 ArcRunnable<E>,
83 BoxRunnable,
84 RcRunnable,
85 FnMut() -> Result<(), E>
86 );
87}
88
89impl<E> SupplierOnce<Result<(), E>> for BoxRunnable<E> {
90 /// Executes the boxed runnable as a one-time supplier of `Result<(), E>`.
91 #[inline]
92 fn get(mut self) -> Result<(), E> {
93 self.run()
94 }
95}
96
97impl_closure_trait!(
98 Runnable<E>,
99 run,
100 FnMut() -> Result<(), E>
101);
102
103impl_supplier_debug_display!(BoxRunnable<E>);