Skip to main content

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