use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::Duration; use tokio::sync::oneshot::{channel, Receiver}; #[tokio::main] async fn main() { let (tx1, rx1) = channel::(); let (_tx2, rx2) = channel::(); tokio::spawn(async move { tokio::time::sleep(Duration::from_millis(200)).await; let _ = tx1.send(1); }); println!("start select"); MySelect { rx1, rx2 }.await; println!("end select"); } struct MySelect { rx1: Receiver, rx2: Receiver, } impl Future for MySelect { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { if let Poll::Ready(val) = Pin::new(&mut self.rx1).poll(cx) { println!("rx1 completed first with {:?}", val); return Poll::Ready(()); } if let Poll::Ready(val) = Pin::new(&mut self.rx2).poll(cx) { println!("rx2 completed first with {:?}", val); return Poll::Ready(()); } Poll::Pending } }