Skip to content

Commit 7af1744

Browse files
authored
feat: Add TokioTimer to rt::tokio module (#73)
1 parent 1dd414e commit 7af1744

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

src/rt/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
pub mod tokio;
55

66
#[cfg(feature = "tokio")]
7-
pub use self::tokio::{TokioExecutor, TokioIo};
7+
pub use self::tokio::{TokioExecutor, TokioIo, TokioTimer};

src/rt/tokio.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use std::{
44
future::Future,
55
pin::Pin,
66
task::{Context, Poll},
7+
time::{Duration, Instant},
78
};
89

9-
use hyper::rt::Executor;
10+
use hyper::rt::{Executor, Sleep, Timer};
1011
use pin_project_lite::pin_project;
1112

1213
/// Future executor that utilises `tokio` threads.
@@ -24,6 +25,21 @@ pin_project! {
2425
}
2526
}
2627

28+
/// A Timer that uses the tokio runtime.
29+
#[non_exhaustive]
30+
#[derive(Default, Clone, Debug)]
31+
pub struct TokioTimer;
32+
33+
// Use TokioSleep to get tokio::time::Sleep to implement Unpin.
34+
// see https://docs.rs/tokio/latest/tokio/time/struct.Sleep.html
35+
pin_project! {
36+
#[derive(Debug)]
37+
struct TokioSleep {
38+
#[pin]
39+
inner: tokio::time::Sleep,
40+
}
41+
}
42+
2743
// ===== impl TokioExecutor =====
2844

2945
impl<Fut> Executor<Fut> for TokioExecutor
@@ -190,6 +206,51 @@ where
190206
}
191207
}
192208

209+
// ==== impl TokioTimer =====
210+
211+
impl Timer for TokioTimer {
212+
fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
213+
Box::pin(TokioSleep {
214+
inner: tokio::time::sleep(duration),
215+
})
216+
}
217+
218+
fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
219+
Box::pin(TokioSleep {
220+
inner: tokio::time::sleep_until(deadline.into()),
221+
})
222+
}
223+
224+
fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
225+
if let Some(sleep) = sleep.as_mut().downcast_mut_pin::<TokioSleep>() {
226+
sleep.reset(new_deadline)
227+
}
228+
}
229+
}
230+
231+
impl TokioTimer {
232+
/// Create a new TokioTimer
233+
pub fn new() -> Self {
234+
Self {}
235+
}
236+
}
237+
238+
impl Future for TokioSleep {
239+
type Output = ();
240+
241+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
242+
self.project().inner.poll(cx)
243+
}
244+
}
245+
246+
impl Sleep for TokioSleep {}
247+
248+
impl TokioSleep {
249+
fn reset(self: Pin<&mut Self>, deadline: Instant) {
250+
self.project().inner.as_mut().reset(deadline.into());
251+
}
252+
}
253+
193254
#[cfg(test)]
194255
mod tests {
195256
use crate::rt::TokioExecutor;

0 commit comments

Comments
 (0)