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
13use std::cell::RefCell;
14use std::rc::Rc;
15
16use crate::{
17    macros::{
18        impl_common_name_methods,
19        impl_common_new_methods,
20        impl_rc_conversions,
21    },
22    suppliers::{
23        macros::impl_supplier_debug_display,
24        supplier::Supplier,
25    },
26    tasks::runnable::{
27        BoxRunnable,
28        Runnable,
29    },
30};
31
32// ============================================================================
33// RcRunnable
34// ============================================================================
35
36/// Single-threaded shared runnable.
37///
38/// `RcRunnable<E>` stores a `Rc<RefCell<dyn FnMut() -> Result<(), E>>>` and can
39/// be called repeatedly through shared ownership.
40///
41/// # Type Parameters
42///
43/// * `E` - The error value returned when the action fails.
44///
45pub struct RcRunnable<E> {
46    /// The stateful closure executed by this runnable.
47    pub(super) function: Rc<RefCell<dyn FnMut() -> Result<(), E>>>,
48    /// The optional name of this runnable.
49    pub(super) name: Option<String>,
50}
51
52impl<E> Clone for RcRunnable<E> {
53    #[inline]
54    fn clone(&self) -> Self {
55        Self {
56            function: Rc::clone(&self.function),
57            name: self.name.clone(),
58        }
59    }
60}
61
62impl<E> RcRunnable<E> {
63    impl_common_new_methods!(
64        (FnMut() -> Result<(), E> + 'static),
65        |function| Rc::new(RefCell::new(function)),
66        "runnable"
67    );
68
69    /// Creates a shared runnable from a reusable supplier.
70    ///
71    /// # Parameters
72    ///
73    /// * `supplier` - The supplier that produces the runnable result.
74    ///
75    /// # Returns
76    ///
77    /// A new `RcRunnable<E>`.
78    #[inline]
79    pub fn from_supplier<S>(supplier: S) -> Self
80    where
81        S: Supplier<Result<(), E>> + 'static,
82    {
83        Self::new(move || supplier.get())
84    }
85
86    impl_common_name_methods!("runnable");
87}
88
89impl<E> Runnable<E> for RcRunnable<E> {
90    /// Executes the shared runnable.
91    #[inline]
92    fn run(&mut self) -> Result<(), E> {
93        (self.function.borrow_mut())()
94    }
95
96    impl_rc_conversions!(
97        RcRunnable<E>,
98        BoxRunnable,
99        FnMut() -> Result<(), E>
100    );
101}
102
103impl_supplier_debug_display!(RcRunnable<E>);