@@ -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 } ;
1011use 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
2945impl < 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) ]
194255mod tests {
195256 use crate :: rt:: TokioExecutor ;
0 commit comments