Created
August 14, 2020 14:35
-
-
Save Minoru/556e51936dd9f2dcc92e053c3eb066ea to your computer and use it in GitHub Desktop.
A better TwoFutures re-implementation for https://www.snoyman.com/blog/2019/12/rust-crash-course-08-down-dirty-future
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use async_std::task::block_on; | |
use async_std::task::{sleep, spawn}; | |
use pin_project_lite::pin_project; | |
use std::future::Future; | |
use std::pin::Pin; | |
use std::task::{Context, Poll}; | |
use std::time::Duration; | |
pin_project! { | |
struct TwoFutures<Fut1, Fut2> { | |
first_done: bool, | |
#[pin] | |
first: Fut1, | |
#[pin] | |
second: Fut2, | |
} | |
} | |
impl<Fut1: Future, Fut2: Future> Future for TwoFutures<Fut1, Fut2> { | |
type Output = Fut2::Output; | |
fn poll(self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> { | |
let this = self.project(); | |
if !*this.first_done { | |
if let Poll::Ready(_) = this.first.poll(ctx) { | |
*this.first_done = true; | |
} | |
} | |
if *this.first_done { | |
this.second.poll(ctx) | |
} else { | |
Poll::Pending | |
} | |
} | |
} | |
fn sleepus() -> impl Future<Output = ()> { | |
TwoFutures { | |
first_done: false, | |
first: sleep(Duration::from_millis(3000)), | |
// The blog post suggests to use an ordinary block here, | |
// but that prints the message *upon construction*. | |
// A better approach is to construct a future here, | |
// so the printing is delayed until the moment | |
// when the future is polled. | |
second: { | |
async_std::future::poll_fn(|_ctx| { | |
println!("Hello TwoFutures"); | |
Poll::Ready(()) | |
}) | |
}, | |
} | |
} | |
async fn interruptus() { | |
for i in 1..=5 { | |
println!("Interruptus {}", i); | |
sleep(Duration::from_millis(1000)).await; | |
} | |
} | |
fn main() { | |
block_on(async { | |
let sleepus = spawn(sleepus()); | |
interruptus().await; | |
sleepus.await; | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment