1use std::any::Any;
4use std::convert::Infallible;
5use std::future::Future;
6use std::marker::PhantomData;
7use std::pin::Pin;
8use crate::observer::{ExecutorNotified, TypedObserver, ObserverNotified, Observer, FinishedObservation};
9use crate::{SomeLocalExecutor};
10use crate::task::Task;
11
12pub(crate) struct SomeLocalExecutorErasingNotifier<'borrow, 'underlying, UnderlyingExecutor: SomeLocalExecutor<'underlying> + ?Sized> {
16 executor: &'borrow mut UnderlyingExecutor,
17 _phantom: PhantomData<&'underlying ()>
18}
19
20impl <'borrow, 'underlying, UnderlyingExecutor: SomeLocalExecutor<'underlying> + ?Sized> SomeLocalExecutorErasingNotifier<'borrow, 'underlying, UnderlyingExecutor> {
21 pub(crate) fn new(executor: &'borrow mut UnderlyingExecutor) -> Self {
22 Self {
23 executor,
24 _phantom: PhantomData
25 }
26 }
27}
28
29impl<'borrow, 'executor, UnderlyingExecutor: SomeLocalExecutor<'executor>> SomeLocalExecutor<'executor> for SomeLocalExecutorErasingNotifier<'borrow, 'executor, UnderlyingExecutor> {
30 type ExecutorNotifier = Box<dyn ExecutorNotified>;
31
32 fn spawn_local<F: Future, Notifier: ObserverNotified<F::Output>>(&mut self, task: Task<F, Notifier>) -> impl Observer<Value=F::Output>
33 where
34 Self: Sized,
35 F: 'executor,
36 <F as Future>::Output: Unpin,
38 <F as Future>::Output: 'static,
39 {
40 self.executor.spawn_local(task)
41 }
42
43 fn spawn_local_async<F: Future, Notifier: ObserverNotified<F::Output>>(&mut self, task: Task<F, Notifier>) -> impl Future<Output=impl Observer<Value=F::Output>>
44 where
45 Self: Sized,
46 F: 'executor,
47 F::Output: 'static + Unpin,
48 {
49 async {
50 self.executor.spawn_local_async(task).await
51 }
52 }
53
54
55 fn spawn_local_objsafe(&mut self, task: Task<Pin<Box<dyn Future<Output=Box<dyn Any>>>>, Box<dyn ObserverNotified<(dyn Any + 'static)>>>) -> Box<dyn Observer<Value=Box<dyn Any>, Output = FinishedObservation<Box<dyn Any>>>> {
56 self.executor.spawn_local_objsafe(task)
57 }
58
59 fn spawn_local_objsafe_async<'s>(&'s mut self, task: Task<Pin<Box<dyn Future<Output=Box<dyn Any>>>>, Box<dyn ObserverNotified<(dyn Any + 'static)>>>) -> Box<dyn Future<Output=Box<dyn Observer<Value=Box<dyn Any>, Output = FinishedObservation<Box<dyn Any>>>>> + 's> {
60 Box::new(async {
61 let objsafe_spawn_fut = self.executor.spawn_local_objsafe_async(task);
62 Box::into_pin(objsafe_spawn_fut).await
63 })
64 }
65
66
67 fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier> {
68 self.executor.executor_notifier().map(|x| Box::new(x) as Self::ExecutorNotifier)
69 }
70}
71
72pub(crate) struct OwnedSomeLocalExecutorErasingNotifier<'underlying, UnderlyingExecutor> {
77 executor: UnderlyingExecutor,
78 _phantom: PhantomData<&'underlying ()>
79}
80
81impl<'underlying,UnderlyingExecutor> OwnedSomeLocalExecutorErasingNotifier<'underlying,UnderlyingExecutor> {
82 pub(crate) fn new(executor: UnderlyingExecutor) -> Self {
83 Self {
84 executor,
85 _phantom: PhantomData
86 }
87 }
88}
89
90impl <'underlying, UnderlyingExecutor: SomeLocalExecutor<'underlying>> SomeLocalExecutor<'underlying> for OwnedSomeLocalExecutorErasingNotifier<'underlying, UnderlyingExecutor> {
91 type ExecutorNotifier = Box<dyn ExecutorNotified>;
92
93 fn spawn_local<F: Future, Notifier: ObserverNotified<F::Output>>(&mut self, task: Task<F, Notifier>) -> impl Observer<Value=F::Output>
94 where
95 Self: Sized,
96 F: 'underlying,
97 <F as Future>::Output: Unpin,
99 <F as Future>::Output: 'static,
100 {
101 self.executor.spawn_local(task)
102 }
103
104 fn spawn_local_async<F: Future, Notifier: ObserverNotified<F::Output>>(&mut self, task: Task<F, Notifier>) -> impl Future<Output=impl Observer<Value=F::Output>>
105 where
106 Self: Sized,
107 F: 'underlying,
108 F::Output: 'static + Unpin,
109 {
110 async {
111 self.executor.spawn_local_async(task).await
112 }
113 }
114
115 fn spawn_local_objsafe(&mut self, task: Task<Pin<Box<dyn Future<Output=Box<dyn Any>>>>, Box<dyn ObserverNotified<(dyn Any + 'static)>>>) -> Box<dyn Observer<Value=Box<dyn Any>, Output=FinishedObservation<Box<dyn Any>>>> {
116 self.executor.spawn_local_objsafe(task)
117 }
118
119 fn spawn_local_objsafe_async<'s>(&'s mut self, task: Task<Pin<Box<dyn Future<Output=Box<dyn Any>>>>, Box<dyn ObserverNotified<(dyn Any + 'static)>>>) -> Box<dyn Future<Output=Box<dyn Observer<Value=Box<dyn Any>, Output=FinishedObservation<Box<dyn Any>>>>> + 's> {
120 Box::new(async {
121 let objsafe_spawn_fut = self.executor.spawn_local_objsafe_async(task);
122 Box::into_pin(objsafe_spawn_fut).await
123 })
124 }
125
126 fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier> {
127 self.executor.executor_notifier().map(|x| Box::new(x) as Self::ExecutorNotifier)
128 }
129}
130
131
132pub (crate) struct UnsafeErasedLocalExecutor {
133 underlying: *mut dyn SomeLocalExecutor<'static, ExecutorNotifier=Box<dyn ExecutorNotified>>,
134}
135
136impl UnsafeErasedLocalExecutor {
137 pub unsafe fn new<'e>(underlying:&mut (dyn SomeLocalExecutor<ExecutorNotifier=Box<dyn ExecutorNotified>> + 'e)) -> Self {
145 Self {
146 underlying: std::mem::transmute(underlying),
147 }
148 }
149
150 fn executor(&mut self) -> &mut (dyn SomeLocalExecutor<ExecutorNotifier=Box<dyn ExecutorNotified>> + '_) {
151 unsafe {
153 std::mem::transmute::<
154 &mut dyn SomeLocalExecutor<ExecutorNotifier=Box<dyn ExecutorNotified>>,
155 &mut dyn SomeLocalExecutor<ExecutorNotifier=Box<dyn ExecutorNotified>>
156 >(&mut *self.underlying)
157 }
158 }
159}
160
161impl<'a> SomeLocalExecutor<'a> for UnsafeErasedLocalExecutor {
162 type ExecutorNotifier = Box<dyn ExecutorNotified>;
163
164 fn spawn_local<F: Future, Notifier: ObserverNotified<F::Output>>(&mut self, _task: Task<F, Notifier>) -> impl Observer<Value=F::Output>
165 where
166 Self: Sized,
167 F: 'a,
168 <F as Future>::Output: Unpin,
170 <F as Future>::Output: 'static,
171 {
172 #[allow(unreachable_code)] {
173 unimplemented!("Not implemented for erased executor; use objsafe method") as TypedObserver<F::Output, Infallible>
174 }
175 }
176
177 fn spawn_local_async<F: Future, Notifier: ObserverNotified<F::Output>>(&mut self, _task: Task<F, Notifier>) -> impl Future<Output=impl Observer<Value=F::Output>>
178 where
179 Self: Sized,
180 F::Output: 'static,
181 {
182 #[allow(unreachable_code)] {
183 async { unimplemented!("Not implemented for erased executor; use objsafe method") as TypedObserver<F::Output, Infallible> }
184 }
185 }
186
187 fn spawn_local_objsafe(&mut self, task: Task<Pin<Box<dyn Future<Output=Box<dyn Any>>>>, Box<dyn ObserverNotified<(dyn Any + 'static)>>>) -> Box<dyn Observer<Value=Box<dyn Any>, Output = FinishedObservation<Box<dyn Any>>>> {
188 let ex = self.executor();
189 ex.spawn_local_objsafe(task)
190 }
191
192 fn spawn_local_objsafe_async<'s>(&'s mut self, task: Task<Pin<Box<dyn Future<Output=Box<dyn Any>>>>, Box<dyn ObserverNotified<(dyn Any + 'static)>>>) -> Box<dyn Future<Output=Box<dyn Observer<Value=Box<dyn Any>, Output = FinishedObservation<Box<dyn Any>>>>> + 's> {
193 let ex = self.executor();
194 ex.spawn_local_objsafe_async(task)
195 }
196
197 fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier> {
198 self.executor().executor_notifier()
199 }
200}