Skip to main content

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