Skip to content

Commit fc9e8f3

Browse files
committed
feat: add downcast on Sleep trait
This commit adds `as_any` downcast method for the `Sleep` trait. BREAKING CHANGE: `Sleep` trait now needs `as_any` implementation
1 parent 5bf1640 commit fc9e8f3

File tree

3 files changed

+141
-35
lines changed

3 files changed

+141
-35
lines changed

src/rt.rs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/rt/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//! Runtime components
2+
//!
3+
//! By default, hyper includes the [tokio](https://tokio.rs) runtime.
4+
//!
5+
//! If the `runtime` feature is disabled, the types in this module can be used
6+
//! to plug in other runtimes.
7+
8+
pub mod timer;
9+
10+
/// An executor of futures.
11+
pub trait Executor<Fut> {
12+
/// Place the future into the executor to be run.
13+
fn execute(&self, fut: Fut);
14+
}

src/rt/timer.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//! Provides a timer trait with timer-like functions
2+
//!
3+
//! Example using tokio timer:
4+
//! ```rust
5+
//! use std::{
6+
//! pin::Pin,
7+
//! task::{Context, Poll},
8+
//! time::{Duration, Instant},
9+
//! };
10+
//!
11+
//! use futures_util::Future;
12+
//! use pin_project_lite::pin_project;
13+
//! use hyper::rt::timer::{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 sleep.downcast_ref::<>().is_some() {
33+
//! *sleep = self.sleep_until(new_deadline);
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+
56+
use std::{
57+
any::TypeId,
58+
future::Future,
59+
pin::Pin,
60+
time::{Duration, Instant},
61+
};
62+
63+
/// A timer which provides timer-like functions.
64+
pub trait Timer {
65+
/// Return a future that resolves in `duration` time.
66+
fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>>;
67+
68+
/// Return a future that resolves at `deadline`.
69+
fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>>;
70+
71+
/// Reset a future to resolve at `new_deadline` instead.
72+
fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
73+
*sleep = self.sleep_until(new_deadline);
74+
}
75+
}
76+
77+
/// A future returned by a `Timer`.
78+
pub trait Sleep: Send + Sync + Future<Output = ()> {
79+
/// This method is private and should not be implemented by downstream crate
80+
fn type_id(&self, _: private::Sealed) -> TypeId
81+
where
82+
Self: 'static,
83+
{
84+
TypeId::of::<Self>()
85+
}
86+
}
87+
88+
impl dyn Sleep {
89+
//! This is a re-implementation of downcast methods from std::any::Any
90+
91+
/// Check whether the type
92+
pub fn is<T>(&self) -> bool
93+
where
94+
T: Sleep + 'static,
95+
{
96+
self.type_id(private::Sealed {}) == TypeId::of::<T>()
97+
}
98+
99+
/// Downcast the Sleep object to its original type
100+
pub fn downcast_ref<T>(&self) -> Option<&T>
101+
where
102+
T: Sleep + 'static,
103+
{
104+
if self.is::<T>() {
105+
unsafe { Some(&*(self as *const dyn Sleep as *const T)) }
106+
} else {
107+
None
108+
}
109+
}
110+
111+
/// Similar to `downcast_ref` but returns a mutable version instead
112+
pub fn downcast_mut<T>(&mut self) -> Option<&mut T>
113+
where
114+
T: Sleep + 'static,
115+
{
116+
if self.is::<T>() {
117+
unsafe { Some(&mut *(self as *mut dyn Sleep as *mut T)) }
118+
} else {
119+
None
120+
}
121+
}
122+
}
123+
124+
mod private {
125+
#![allow(missing_debug_implementations)]
126+
pub struct Sealed {}
127+
}

0 commit comments

Comments
 (0)