qubit_function/tasks/runnable_with.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # RunnableWith Types
10//!
11//! Provides fallible, reusable actions that operate on a mutable input.
12//!
13//! A `RunnableWith<T, E>` is equivalent to
14//! `FnMut(&mut T) -> Result<(), E>`, but uses task-oriented vocabulary. Use it
15//! when the operation needs access to protected or caller-provided state and
16//! only success or failure should be reported.
17//!
18//! The trait itself does not require `Send`; concurrent executors should add
19//! `+ Send + 'static` at their API boundary.
20//!
21//! # Author
22//!
23//! Haixing Hu
24
25use std::cell::RefCell;
26use std::rc::Rc;
27use std::sync::Arc;
28
29use parking_lot::Mutex;
30
31use crate::{
32 functions::macros::impl_function_debug_display,
33 macros::{
34 impl_arc_conversions,
35 impl_box_conversions,
36 impl_closure_trait,
37 impl_common_name_methods,
38 impl_common_new_methods,
39 impl_rc_conversions,
40 },
41 tasks::callable_with::BoxCallableWith,
42};
43
44mod box_runnable_with;
45pub use box_runnable_with::BoxRunnableWith;
46mod rc_runnable_with;
47pub use rc_runnable_with::RcRunnableWith;
48mod arc_runnable_with;
49pub use arc_runnable_with::ArcRunnableWith;
50
51/// A fallible, reusable action that receives mutable input.
52///
53/// Conceptually this is `FnMut(&mut T) -> Result<(), E>` with task-oriented
54/// naming. It is useful for executor-style APIs that run an action with access
55/// to protected state, such as a value held under a lock.
56///
57/// # Type Parameters
58///
59/// * `T` - The mutable input type.
60/// * `E` - The error value returned when the action fails.
61///
62/// # Author
63///
64/// Haixing Hu
65pub trait RunnableWith<T, E> {
66 /// Executes the action with mutable input.
67 ///
68 /// # Parameters
69 ///
70 /// * `input` - The mutable input passed to this task.
71 ///
72 /// # Returns
73 ///
74 /// Returns `Ok(())` when the action succeeds, or `Err(E)` when it fails.
75 /// The exact error meaning is defined by the concrete runnable.
76 fn run_with(&mut self, input: &mut T) -> Result<(), E>;
77
78 /// Converts this runnable into a boxed runnable.
79 ///
80 /// # Returns
81 ///
82 /// A `BoxRunnableWith<T, E>`.
83 fn into_box(mut self) -> BoxRunnableWith<T, E>
84 where
85 Self: Sized + 'static,
86 {
87 BoxRunnableWith::new(move |input| self.run_with(input))
88 }
89
90 /// Converts this runnable into an `Rc` runnable.
91 ///
92 /// # Returns
93 ///
94 /// A `RcRunnableWith<T, E>`.
95 fn into_rc(mut self) -> RcRunnableWith<T, E>
96 where
97 Self: Sized + 'static,
98 {
99 RcRunnableWith::new(move |input| self.run_with(input))
100 }
101
102 /// Converts this runnable into an `Arc` runnable.
103 ///
104 /// # Returns
105 ///
106 /// An `ArcRunnableWith<T, E>`.
107 fn into_arc(mut self) -> ArcRunnableWith<T, E>
108 where
109 Self: Sized + Send + 'static,
110 {
111 ArcRunnableWith::new(move |input| self.run_with(input))
112 }
113
114 /// Converts this runnable into a mutable closure.
115 ///
116 /// # Returns
117 ///
118 /// A closure implementing `FnMut(&mut T) -> Result<(), E>`.
119 fn into_fn(mut self) -> impl FnMut(&mut T) -> Result<(), E>
120 where
121 Self: Sized + 'static,
122 {
123 move |input| self.run_with(input)
124 }
125
126 /// Converts this runnable into a boxed runnable without consuming `self`.
127 ///
128 /// # Returns
129 ///
130 /// A `BoxRunnableWith<T, E>` built from a clone of this runnable.
131 fn to_box(&self) -> BoxRunnableWith<T, E>
132 where
133 Self: Clone + Sized + 'static,
134 {
135 self.clone().into_box()
136 }
137
138 /// Converts this runnable into an `Rc` runnable without consuming `self`.
139 ///
140 /// # Returns
141 ///
142 /// A `RcRunnableWith<T, E>` built from a clone of this runnable.
143 fn to_rc(&self) -> RcRunnableWith<T, E>
144 where
145 Self: Clone + Sized + 'static,
146 {
147 self.clone().into_rc()
148 }
149
150 /// Converts this runnable into an `Arc` runnable without consuming `self`.
151 ///
152 /// # Returns
153 ///
154 /// An `ArcRunnableWith<T, E>` built from a clone of this runnable.
155 fn to_arc(&self) -> ArcRunnableWith<T, E>
156 where
157 Self: Clone + Send + Sized + 'static,
158 {
159 self.clone().into_arc()
160 }
161
162 /// Converts this runnable into a mutable closure without consuming `self`.
163 ///
164 /// # Returns
165 ///
166 /// A closure implementing `FnMut(&mut T) -> Result<(), E>`.
167 fn to_fn(&self) -> impl FnMut(&mut T) -> Result<(), E>
168 where
169 Self: Clone + Sized + 'static,
170 {
171 self.clone().into_fn()
172 }
173
174 /// Converts this runnable into a callable returning unit.
175 ///
176 /// # Returns
177 ///
178 /// A `BoxCallableWith<T, (), E>` that runs this task and returns unit on
179 /// success.
180 fn into_callable_with(mut self) -> BoxCallableWith<T, (), E>
181 where
182 Self: Sized + 'static,
183 {
184 BoxCallableWith::new(move |input| self.run_with(input))
185 }
186}