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