Skip to main content

qubit_function/tasks/runnable/
arc_runnable.rs

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