caco3_web/
future.rs

1use std::future::Future;
2use std::thread::panicking;
3
4impl<Fut> OnUncompletedDrop for Fut where Fut: Future + Send {}
5
6pub trait OnUncompletedDrop: Future + Send + Sized {
7    /// Call given closure `f` when uncompleted future is dropped.
8    ///
9    /// if `panic` is true, `f` is also called on panic.
10    fn on_uncompleted_drop<F>(self, panic: bool, f: F) -> impl Future<Output = Self::Output> + Send
11    where
12        F: FnOnce() + Send,
13    {
14        let drop_guard = UncompletedDropGuard { f: Some(f), panic };
15        async move {
16            let output = self.await;
17            core::mem::forget(drop_guard);
18            output
19        }
20    }
21}
22
23struct UncompletedDropGuard<F>
24where
25    F: FnOnce() + Send,
26{
27    f: Option<F>,
28    panic: bool,
29}
30
31impl<F> Drop for UncompletedDropGuard<F>
32where
33    F: FnOnce() + Send,
34{
35    fn drop(&mut self) {
36        if let Some(f) = self.f.take() {
37            if self.panic || !panicking() {
38                f()
39            }
40        }
41    }
42}
43
44impl<Fut> OnUncompletedDropLocal for Fut where Fut: Future {}
45
46pub trait OnUncompletedDropLocal: Future + Sized {
47    /// Call given closure `f` when uncompleted future is dropped.
48    ///
49    /// if `panic` is true, `f` is also called on panic.
50    fn on_uncompleted_drop_local<F: FnOnce()>(
51        self,
52        panic: bool,
53        f: F,
54    ) -> impl Future<Output = Self::Output> {
55        let drop_guard = UncompletedDropGuardLocal { f: Some(f), panic };
56        async move {
57            let output = self.await;
58            core::mem::forget(drop_guard);
59            output
60        }
61    }
62}
63
64struct UncompletedDropGuardLocal<F>
65where
66    F: FnOnce(),
67{
68    f: Option<F>,
69    panic: bool,
70}
71
72impl<F> Drop for UncompletedDropGuardLocal<F>
73where
74    F: FnOnce(),
75{
76    fn drop(&mut self) {
77        if let Some(f) = self.f.take() {
78            if self.panic || !panicking() {
79                f()
80            }
81        }
82    }
83}