smol_hyper/rt/
smol.rs

1// MOT/Apache2 License
2
3//! Integrations with `hyper::rt` for `smol` types.
4
5use async_executor::Executor;
6use hyper::rt::Sleep;
7
8use std::future::Future;
9use std::pin::Pin;
10use std::task::{Context, Poll};
11use std::time::{Duration, Instant};
12
13/// Use an [`async-executor`] as an executor.
14#[derive(Debug, Clone)]
15pub struct SmolExecutor<E: ?Sized>(E);
16
17impl<E> From<E> for SmolExecutor<E> {
18    #[inline]
19    fn from(inner: E) -> Self {
20        Self(inner)
21    }
22}
23
24impl<E> SmolExecutor<E> {
25    /// Create a new `SmolExecutor` based around something that derefs to an [`Executor`].
26    pub fn new(inner: E) -> Self {
27        inner.into()
28    }
29
30    /// Get the inner type.
31    #[inline]
32    pub fn into_inner(self) -> E {
33        self.0
34    }
35}
36
37impl<E: ?Sized> SmolExecutor<E> {
38    /// Get a reference to the underlying executor.
39    pub fn get_ref(&self) -> &E {
40        &self.0
41    }
42
43    /// Get a mutable reference to the underlying executor.
44    pub fn get_mut(&mut self) -> &mut E {
45        &mut self.0
46    }
47}
48
49impl<E: ?Sized> AsRef<E> for SmolExecutor<E> {
50    #[inline]
51    fn as_ref(&self) -> &E {
52        self.get_ref()
53    }
54}
55
56impl<E: ?Sized> AsMut<E> for SmolExecutor<E> {
57    #[inline]
58    fn as_mut(&mut self) -> &mut E {
59        self.get_mut()
60    }
61}
62
63impl<'a, E: AsRef<Executor<'a>> + ?Sized, Fut: Future + Send + 'a> hyper::rt::Executor<Fut>
64    for SmolExecutor<E>
65where
66    Fut::Output: Send + 'a,
67{
68    #[inline]
69    fn execute(&self, fut: Fut) {
70        self.get_ref().as_ref().spawn(fut).detach();
71    }
72}
73
74/// Use the timer from [`async-io`].
75#[derive(Debug, Clone, Default)]
76pub struct SmolTimer {
77    _private: (),
78}
79
80impl SmolTimer {
81    /// Create a new `SmolTimer`.
82    #[inline]
83    pub fn new() -> Self {
84        Self::default()
85    }
86}
87
88impl hyper::rt::Timer for SmolTimer {
89    #[inline]
90    fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
91        Box::pin(SmolSleep(async_io::Timer::after(duration)))
92    }
93
94    #[inline]
95    fn sleep_until(&self, at: Instant) -> Pin<Box<dyn Sleep>> {
96        Box::pin(SmolSleep(async_io::Timer::at(at)))
97    }
98
99    #[inline]
100    fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
101        if let Some(mut sleep) = sleep.as_mut().downcast_mut_pin::<SmolSleep>() {
102            sleep.0.set_at(new_deadline);
103        } else {
104            *sleep = Box::pin(SmolSleep(async_io::Timer::at(new_deadline)));
105        }
106    }
107}
108
109struct SmolSleep(async_io::Timer);
110
111impl Future for SmolSleep {
112    type Output = ();
113
114    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
115        match Pin::new(&mut self.0).poll(cx) {
116            Poll::Ready(_) => Poll::Ready(()),
117            Poll::Pending => Poll::Pending,
118        }
119    }
120}
121
122impl Sleep for SmolSleep {}