qubit_function/tasks/callable_with.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # CallableWith Types
10//!
11//! Provides fallible, reusable computations that operate on a mutable input.
12//!
13//! A `CallableWith<T, R, E>` is equivalent to
14//! `FnMut(&mut T) -> Result<R, E>`, but uses task-oriented vocabulary. Use it
15//! when the operation needs access to protected or caller-provided state and
16//! returns a success value.
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::runnable_with::BoxRunnableWith,
42};
43
44mod box_callable_with;
45pub use box_callable_with::BoxCallableWith;
46mod rc_callable_with;
47pub use rc_callable_with::RcCallableWith;
48mod arc_callable_with;
49pub use arc_callable_with::ArcCallableWith;
50
51/// A fallible, reusable computation that receives mutable input.
52///
53/// Conceptually this is `FnMut(&mut T) -> Result<R, E>` with task-oriented
54/// naming. It is useful for executor-style APIs that run a task with access to
55/// protected state, such as a value held under a lock.
56///
57/// # Type Parameters
58///
59/// * `T` - The mutable input type.
60/// * `R` - The success value returned by the computation.
61/// * `E` - The error value returned when the computation fails.
62///
63/// # Author
64///
65/// Haixing Hu
66pub trait CallableWith<T, R, E> {
67 /// Executes the computation with mutable input.
68 ///
69 /// # Parameters
70 ///
71 /// * `input` - The mutable input passed to this task.
72 ///
73 /// # Returns
74 ///
75 /// Returns `Ok(R)` when the computation succeeds, or `Err(E)` when it
76 /// fails. The exact error meaning is defined by the concrete callable.
77 fn call_with(&mut self, input: &mut T) -> Result<R, E>;
78
79 /// Converts this callable into a boxed callable.
80 ///
81 /// # Returns
82 ///
83 /// A `BoxCallableWith<T, R, E>`.
84 fn into_box(mut self) -> BoxCallableWith<T, R, E>
85 where
86 Self: Sized + 'static,
87 {
88 BoxCallableWith::new(move |input| self.call_with(input))
89 }
90
91 /// Converts this callable into an `Rc` callable.
92 ///
93 /// # Returns
94 ///
95 /// A `RcCallableWith<T, R, E>`.
96 fn into_rc(mut self) -> RcCallableWith<T, R, E>
97 where
98 Self: Sized + 'static,
99 {
100 RcCallableWith::new(move |input| self.call_with(input))
101 }
102
103 /// Converts this callable into an `Arc` callable.
104 ///
105 /// # Returns
106 ///
107 /// An `ArcCallableWith<T, R, E>`.
108 fn into_arc(mut self) -> ArcCallableWith<T, R, E>
109 where
110 Self: Sized + Send + 'static,
111 {
112 ArcCallableWith::new(move |input| self.call_with(input))
113 }
114
115 /// Converts this callable into a mutable closure.
116 ///
117 /// # Returns
118 ///
119 /// A closure implementing `FnMut(&mut T) -> Result<R, E>`.
120 fn into_fn(mut self) -> impl FnMut(&mut T) -> Result<R, E>
121 where
122 Self: Sized + 'static,
123 {
124 move |input| self.call_with(input)
125 }
126
127 /// Converts this callable into a boxed callable without consuming `self`.
128 ///
129 /// # Returns
130 ///
131 /// A `BoxCallableWith<T, R, E>` built from a clone of this callable.
132 fn to_box(&self) -> BoxCallableWith<T, R, E>
133 where
134 Self: Clone + Sized + 'static,
135 {
136 self.clone().into_box()
137 }
138
139 /// Converts this callable into an `Rc` callable without consuming `self`.
140 ///
141 /// # Returns
142 ///
143 /// A `RcCallableWith<T, R, E>` built from a clone of this callable.
144 fn to_rc(&self) -> RcCallableWith<T, R, E>
145 where
146 Self: Clone + Sized + 'static,
147 {
148 self.clone().into_rc()
149 }
150
151 /// Converts this callable into an `Arc` callable without consuming `self`.
152 ///
153 /// # Returns
154 ///
155 /// An `ArcCallableWith<T, R, E>` built from a clone of this callable.
156 fn to_arc(&self) -> ArcCallableWith<T, R, E>
157 where
158 Self: Clone + Send + Sized + 'static,
159 {
160 self.clone().into_arc()
161 }
162
163 /// Converts this callable into a mutable closure without consuming `self`.
164 ///
165 /// # Returns
166 ///
167 /// A closure implementing `FnMut(&mut T) -> Result<R, E>`.
168 fn to_fn(&self) -> impl FnMut(&mut T) -> Result<R, E>
169 where
170 Self: Clone + Sized + 'static,
171 {
172 self.clone().into_fn()
173 }
174
175 /// Converts this callable into a runnable by discarding the success value.
176 ///
177 /// # Returns
178 ///
179 /// A `BoxRunnableWith<T, E>` preserving errors and mapping success to unit.
180 fn into_runnable_with(mut self) -> BoxRunnableWith<T, E>
181 where
182 Self: Sized + 'static,
183 {
184 BoxRunnableWith::new(move |input| self.call_with(input).map(|_| ()))
185 }
186}