qubit_function/tasks/callable_with/
box_callable_with.rs1use crate::{
14 macros::{
15 impl_box_conversions,
16 impl_common_name_methods,
17 impl_common_new_methods,
18 },
19 tasks::{
20 callable_with::{
21 CallableWith,
22 RcCallableWith,
23 },
24 runnable_with::BoxRunnableWith,
25 },
26};
27
28type BoxCallableWithFn<T, R, E> = Box<dyn FnMut(&mut T) -> Result<R, E>>;
29
30pub struct BoxCallableWith<T, R, E> {
36 pub(super) function: BoxCallableWithFn<T, R, E>,
38 pub(super) name: Option<String>,
40}
41
42impl<T, R, E> BoxCallableWith<T, R, E> {
43 impl_common_new_methods!(
44 (FnMut(&mut T) -> Result<R, E> + 'static),
45 |function| Box::new(function),
46 "callable-with"
47 );
48
49 impl_common_name_methods!("callable-with");
50
51 #[inline]
61 pub fn map<U, M>(self, mut mapper: M) -> BoxCallableWith<T, U, E>
62 where
63 M: FnMut(R) -> U + 'static,
64 T: 'static,
65 R: 'static,
66 E: 'static,
67 {
68 let name = self.name;
69 let mut function = self.function;
70 BoxCallableWith::new_with_optional_name(move |input| function(input).map(&mut mapper), name)
71 }
72
73 #[inline]
83 pub fn map_err<E2, M>(self, mut mapper: M) -> BoxCallableWith<T, R, E2>
84 where
85 M: FnMut(E) -> E2 + 'static,
86 T: 'static,
87 R: 'static,
88 E: 'static,
89 {
90 let name = self.name;
91 let mut function = self.function;
92 BoxCallableWith::new_with_optional_name(
93 move |input| function(input).map_err(&mut mapper),
94 name,
95 )
96 }
97
98 #[inline]
108 pub fn and_then<U, N>(self, next: N) -> BoxCallableWith<T, U, E>
109 where
110 N: FnMut(R, &mut T) -> Result<U, E> + 'static,
111 T: 'static,
112 R: 'static,
113 E: 'static,
114 {
115 let name = self.name;
116 let mut function = self.function;
117 let mut next = next;
118 BoxCallableWith::new_with_optional_name(
119 move |input| {
120 let value = function(input)?;
121 next(value, input)
122 },
123 name,
124 )
125 }
126}
127
128impl<T, R, E> CallableWith<T, R, E> for BoxCallableWith<T, R, E> {
129 #[inline]
131 fn call_with(&mut self, input: &mut T) -> Result<R, E> {
132 (self.function)(input)
133 }
134
135 impl_box_conversions!(
136 BoxCallableWith<T, R, E>,
137 RcCallableWith,
138 FnMut(&mut T) -> Result<R, E>
139 );
140
141 #[inline]
144 fn into_runnable_with(self) -> BoxRunnableWith<T, E>
145 where
146 Self: Sized + 'static,
147 {
148 let name = self.name;
149 let mut function = self.function;
150 BoxRunnableWith::new_with_optional_name(move |input| function(input).map(|_| ()), name)
151 }
152}