1use std::future::Future;
4use std::pin::Pin;
5use std::task::{Context, Poll};
6use std::thread;
7use std::time::{Duration, Instant};
8
9mod pin_utils;
10mod waker_fn;
11
12#[derive(Default)]
17pub struct Runtime;
18
19impl Runtime {
20 pub fn new() -> Self {
22 Runtime {}
23 }
24
25 pub fn block_on<F: Future>(&self, future: F) -> F::Output {
28 pin_mut!(future);
30
31 let thread = thread::current();
32 let waker = waker_fn::waker_fn(move || thread.unpark());
33 let mut context = Context::from_waker(&waker);
34
35 loop {
36 match future.as_mut().poll(&mut context) {
37 Poll::Ready(output) => return output,
38 Poll::Pending => thread::park(),
39 }
40 }
41 }
42}
43
44#[must_use = "futures do nothing unless you `.await` or poll them"]
46pub struct Sleep {
47 target_time: Instant,
48}
49
50pub fn sleep(duration: Duration) -> Sleep {
53 Sleep {
54 target_time: Instant::now() + duration,
55 }
56}
57
58impl Future for Sleep {
59 type Output = ();
60
61 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
62 if Instant::now() >= self.target_time {
63 return Poll::Ready(());
64 }
65
66 let waker = cx.waker().clone();
68 let target_time = self.target_time;
69 thread::spawn(move || {
70 let now = Instant::now();
71 if now < target_time {
72 thread::sleep(target_time - now);
73 }
74 waker.wake();
75 });
76
77 Poll::Pending
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84 use std::time::Duration;
85
86 #[test]
87 fn it_works_with_a_simple_future() {
88 let rt = Runtime::new();
90
91 let future = async { 5 };
92
93 assert_eq!(rt.block_on(future), 5);
95 }
96
97 #[test]
98 fn it_works_with_a_future_that_yields() {
99 let rt = Runtime::new();
101
102 let future = async {
103 println!("Going to sleep...");
104 sleep(Duration::from_millis(50)).await;
105 println!("Woke up!");
106 10
107 };
108
109 assert_eq!(rt.block_on(future), 10);
111 }
112}