• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::any::Any;
2 use core::pin::Pin;
3 use std::boxed::Box;
4 use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe};
5 
6 use futures_core::future::Future;
7 use futures_core::task::{Context, Poll};
8 use pin_project_lite::pin_project;
9 
10 pin_project! {
11     /// Future for the [`catch_unwind`](super::FutureExt::catch_unwind) method.
12     #[derive(Debug)]
13     #[must_use = "futures do nothing unless you `.await` or poll them"]
14     pub struct CatchUnwind<Fut> {
15         #[pin]
16         future: Fut,
17     }
18 }
19 
20 impl<Fut> CatchUnwind<Fut>
21 where
22     Fut: Future + UnwindSafe,
23 {
new(future: Fut) -> Self24     pub(super) fn new(future: Fut) -> Self {
25         Self { future }
26     }
27 }
28 
29 impl<Fut> Future for CatchUnwind<Fut>
30 where
31     Fut: Future + UnwindSafe,
32 {
33     type Output = Result<Fut::Output, Box<dyn Any + Send>>;
34 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>35     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
36         let f = self.project().future;
37         catch_unwind(AssertUnwindSafe(|| f.poll(cx)))?.map(Ok)
38     }
39 }
40