hyper/rt/
timer.rs

1//! Provides a timer trait with timer-like functions
2//!
3//! Example using tokio timer:
4//! ```rust
5//! use std::{
6//!     future::Future,
7//!     pin::Pin,
8//!     task::{Context, Poll},
9//!     time::{Duration, Instant},
10//! };
11//!
12//! use pin_project_lite::pin_project;
13//! use hyper::rt::{Timer, Sleep};
14//!
15//! #[derive(Clone, Debug)]
16//! pub struct TokioTimer;
17//!
18//! impl Timer for TokioTimer {
19//!     fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
20//!         Box::pin(TokioSleep {
21//!             inner: tokio::time::sleep(duration),
22//!         })
23//!     }
24//!
25//!     fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
26//!         Box::pin(TokioSleep {
27//!             inner: tokio::time::sleep_until(deadline.into()),
28//!         })
29//!     }
30//!
31//!     fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
32//!         if let Some(sleep) = sleep.as_mut().downcast_mut_pin::<TokioSleep>() {
33//!             sleep.reset(new_deadline.into())
34//!         }
35//!     }
36//! }
37//!
38//! pin_project! {
39//!     pub(crate) struct TokioSleep {
40//!         #[pin]
41//!         pub(crate) inner: tokio::time::Sleep,
42//!     }
43//! }
44//!
45//! impl Future for TokioSleep {
46//!     type Output = ();
47//!
48//!     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
49//!         self.project().inner.poll(cx)
50//!     }
51//! }
52//!
53//! impl Sleep for TokioSleep {}
54//!
55//! impl TokioSleep {
56//!     pub fn reset(self: Pin<&mut Self>, deadline: Instant) {
57//!         self.project().inner.as_mut().reset(deadline.into());
58//!     }
59//! }
60//! ```
61
62use std::{
63    any::TypeId,
64    future::Future,
65    pin::Pin,
66    time::{Duration, Instant},
67};
68
69/// A timer which provides timer-like functions.
70pub trait Timer {
71    /// Return a future that resolves in `duration` time.
72    fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>>;
73
74    /// Return a future that resolves at `deadline`.
75    fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>>;
76
77    /// Reset a future to resolve at `new_deadline` instead.
78    fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
79        *sleep = self.sleep_until(new_deadline);
80    }
81}
82
83/// A future returned by a `Timer`.
84pub trait Sleep: Send + Sync + Future<Output = ()> {
85    #[doc(hidden)]
86    /// This method is private and can not be implemented by downstream crate
87    fn __type_id(&self, _: private::Sealed) -> TypeId
88    where
89        Self: 'static,
90    {
91        TypeId::of::<Self>()
92    }
93}
94
95impl dyn Sleep {
96    //! This is a re-implementation of downcast methods from std::any::Any
97
98    /// Check whether the type is the same as `T`
99    pub fn is<T>(&self) -> bool
100    where
101        T: Sleep + 'static,
102    {
103        self.__type_id(private::Sealed {}) == TypeId::of::<T>()
104    }
105
106    /// Downcast a pinned &mut Sleep object to its original type
107    pub fn downcast_mut_pin<T>(self: Pin<&mut Self>) -> Option<Pin<&mut T>>
108    where
109        T: Sleep + 'static,
110    {
111        if self.is::<T>() {
112            unsafe {
113                let inner = Pin::into_inner_unchecked(self);
114                Some(Pin::new_unchecked(
115                    &mut *(&mut *inner as *mut dyn Sleep as *mut T),
116                ))
117            }
118        } else {
119            None
120        }
121    }
122}
123
124mod private {
125    #![allow(missing_debug_implementations)]
126    pub struct Sealed {}
127}