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::<i32>();
    let (_tx2, rx2) = channel::<i32>();

    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<i32>,
    rx2: Receiver<i32>,
}

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
    }
}
