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}