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