Skip to main content

qubit_function/tasks/
callable_with.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//! # CallableWith Types
11//!
12//! Provides fallible, reusable computations that operate on a mutable input.
13//!
14//! A `CallableWith<T, R, E>` is equivalent to
15//! `FnMut(&mut T) -> Result<R, E>`, but uses task-oriented vocabulary. Use it
16//! when the operation needs access to protected or caller-provided state and
17//! returns a success value.
18//!
19//! The trait itself does not require `Send`; concurrent executors should add
20//! `+ Send + 'static` at their API boundary.
21//!
22
23use crate::tasks::runnable_with::BoxRunnableWith;
24
25mod box_callable_with;
26pub use box_callable_with::BoxCallableWith;
27mod rc_callable_with;
28pub use rc_callable_with::RcCallableWith;
29mod arc_callable_with;
30pub use arc_callable_with::ArcCallableWith;
31
32/// A fallible, reusable computation that receives mutable input.
33///
34/// Conceptually this is `FnMut(&mut T) -> Result<R, E>` with task-oriented
35/// naming. It is useful for executor-style APIs that run a task with access to
36/// protected state, such as a value held under a lock.
37///
38/// # Type Parameters
39///
40/// * `T` - The mutable input type.
41/// * `R` - The success value returned by the computation.
42/// * `E` - The error value returned when the computation fails.
43///
44pub trait CallableWith<T, R, E> {
45    /// Executes the computation with mutable input.
46    ///
47    /// # Parameters
48    ///
49    /// * `input` - The mutable input passed to this task.
50    ///
51    /// # Returns
52    ///
53    /// Returns `Ok(R)` when the computation succeeds, or `Err(E)` when it
54    /// fails. The exact error meaning is defined by the concrete callable.
55    fn call_with(&mut self, input: &mut T) -> Result<R, E>;
56
57    /// Converts this callable into a boxed callable.
58    ///
59    /// # Returns
60    ///
61    /// A `BoxCallableWith<T, R, E>`.
62    fn into_box(mut self) -> BoxCallableWith<T, R, E>
63    where
64        Self: Sized + 'static,
65    {
66        BoxCallableWith::new(move |input| self.call_with(input))
67    }
68
69    /// Converts this callable into an `Rc` callable.
70    ///
71    /// # Returns
72    ///
73    /// A `RcCallableWith<T, R, E>`.
74    fn into_rc(mut self) -> RcCallableWith<T, R, E>
75    where
76        Self: Sized + 'static,
77    {
78        RcCallableWith::new(move |input| self.call_with(input))
79    }
80
81    /// Converts this callable into an `Arc` callable.
82    ///
83    /// # Returns
84    ///
85    /// An `ArcCallableWith<T, R, E>`.
86    fn into_arc(mut self) -> ArcCallableWith<T, R, E>
87    where
88        Self: Sized + Send + 'static,
89    {
90        ArcCallableWith::new(move |input| self.call_with(input))
91    }
92
93    /// Converts this callable into a mutable closure.
94    ///
95    /// # Returns
96    ///
97    /// A closure implementing `FnMut(&mut T) -> Result<R, E>`.
98    fn into_fn(mut self) -> impl FnMut(&mut T) -> Result<R, E>
99    where
100        Self: Sized + 'static,
101    {
102        move |input| self.call_with(input)
103    }
104
105    /// Converts this callable into a boxed callable without consuming `self`.
106    ///
107    /// # Returns
108    ///
109    /// A `BoxCallableWith<T, R, E>` built from a clone of this callable.
110    fn to_box(&self) -> BoxCallableWith<T, R, E>
111    where
112        Self: Clone + Sized + 'static,
113    {
114        self.clone().into_box()
115    }
116
117    /// Converts this callable into an `Rc` callable without consuming `self`.
118    ///
119    /// # Returns
120    ///
121    /// A `RcCallableWith<T, R, E>` built from a clone of this callable.
122    fn to_rc(&self) -> RcCallableWith<T, R, E>
123    where
124        Self: Clone + Sized + 'static,
125    {
126        self.clone().into_rc()
127    }
128
129    /// Converts this callable into an `Arc` callable without consuming `self`.
130    ///
131    /// # Returns
132    ///
133    /// An `ArcCallableWith<T, R, E>` built from a clone of this callable.
134    fn to_arc(&self) -> ArcCallableWith<T, R, E>
135    where
136        Self: Clone + Send + Sized + 'static,
137    {
138        self.clone().into_arc()
139    }
140
141    /// Converts this callable into a mutable closure without consuming `self`.
142    ///
143    /// # Returns
144    ///
145    /// A closure implementing `FnMut(&mut T) -> Result<R, E>`.
146    fn to_fn(&self) -> impl FnMut(&mut T) -> Result<R, E>
147    where
148        Self: Clone + Sized + 'static,
149    {
150        self.clone().into_fn()
151    }
152
153    /// Converts this callable into a runnable by discarding the success value.
154    ///
155    /// # Returns
156    ///
157    /// A `BoxRunnableWith<T, E>` preserving errors and mapping success to unit.
158    fn into_runnable_with(mut self) -> BoxRunnableWith<T, E>
159    where
160        Self: Sized + 'static,
161    {
162        BoxRunnableWith::new(move |input| self.call_with(input).map(|_| ()))
163    }
164}