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