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
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>);