1use futures_micro::poll_state;
6use maybe_unwind::{capture_panic_info, maybe_unwind};
7use std::future::Future;
8use std::panic::{self, AssertUnwindSafe};
9use std::pin::Pin;
10use std::task::Poll;
11
12pub use maybe_unwind::Unwind;
13
14pub fn replace_panic_hook() {
16 panic::set_hook(Box::new(|info| { capture_panic_info(info); }));
17}
18
19pub fn chain_panic_hook() {
22 let old = panic::take_hook();
23 panic::set_hook(Box::new(move |info| {
24 capture_panic_info(info);
25 old(info);
26 }));
27}
28
29pub async fn dont_panic<F, T>(future: F) -> Result<T, Unwind>
31where F: Future<Output = T> {
32 poll_state(Some(future), |future, ctx| {
33 if let Some(ref mut fut) = future {
34 let pin = unsafe { Pin::new_unchecked(fut) };
35 match maybe_unwind(AssertUnwindSafe(|| <F as Future>::poll(pin, ctx))) {
36 Ok(Poll::Ready(val)) => Poll::Ready(Ok(val)),
37 Err(unwind) => Poll::Ready(Err(unwind)),
38 Ok(Poll::Pending) => Poll::Pending,
39 }
40 } else { Poll::Pending }
41 }).await
42}