Skip to main content

qubit_function/tasks/runnable/
rc_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 `RcRunnable` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// ============================================================================
16// RcRunnable
17// ============================================================================
18
19/// Single-threaded shared runnable.
20///
21/// `RcRunnable<E>` stores a `Rc<RefCell<dyn FnMut() -> Result<(), E>>>` and can
22/// be called repeatedly through shared ownership.
23///
24/// # Type Parameters
25///
26/// * `E` - The error value returned when the action fails.
27///
28/// # Author
29///
30/// Haixing Hu
31pub struct RcRunnable<E> {
32    /// The stateful closure executed by this runnable.
33    pub(super) function: Rc<RefCell<dyn FnMut() -> Result<(), E>>>,
34    /// The optional name of this runnable.
35    pub(super) name: Option<String>,
36}
37
38impl<E> Clone for RcRunnable<E> {
39    #[inline]
40    fn clone(&self) -> Self {
41        Self {
42            function: Rc::clone(&self.function),
43            name: self.name.clone(),
44        }
45    }
46}
47
48impl<E> RcRunnable<E> {
49    impl_common_new_methods!(
50        (FnMut() -> Result<(), E> + 'static),
51        |function| Rc::new(RefCell::new(function)),
52        "runnable"
53    );
54
55    /// Creates a shared 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 `RcRunnable<E>`.
64    #[inline]
65    pub fn from_supplier<S>(supplier: S) -> Self
66    where
67        S: Supplier<Result<(), E>> + 'static,
68    {
69        Self::new(move || supplier.get())
70    }
71
72    impl_common_name_methods!("runnable");
73}
74
75impl<E> Runnable<E> for RcRunnable<E> {
76    /// Executes the shared runnable.
77    #[inline]
78    fn run(&mut self) -> Result<(), E> {
79        (self.function.borrow_mut())()
80    }
81
82    impl_rc_conversions!(
83        RcRunnable<E>,
84        BoxRunnable,
85        FnMut() -> Result<(), E>
86    );
87}