nio 0.1.4

Async runtime for Rust
Documentation
use nio::{spawn_local, test};
use std::{
    future::{Future, poll_fn},
    pin::Pin,
    task::{Context, Poll},
};

async fn waker() -> std::task::Waker {
    poll_fn(|cx| Poll::Ready(cx.waker().clone())).await
}

#[test]
async fn wakers_are_different() {
    let w1 = waker().await;

    assert!(w1.will_wake(&waker().await));

    spawn_local(async move {
        let w2 = waker().await;

        spawn_local(async move {
            let w3 = waker().await;

            assert!(!w1.will_wake(&w2));
            assert!(!w1.will_wake(&w3));
            assert!(!w2.will_wake(&w3));
        })
        .await
        .unwrap();
    })
    .await
    .unwrap();
}

#[test]
async fn doesnt_poll_after_ready() {
    #[derive(Default)]
    struct Bomb {
        returned_ready: bool,
    }
    impl Future for Bomb {
        type Output = ();

        fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
            if self.returned_ready {
                panic!("Future was polled again after returning Poll::Ready");
            } else {
                self.returned_ready = true;
                Poll::Ready(())
            }
        }
    }
    Bomb::default().await
}

#[test]
async fn yield_now() {
    let mut yielded = false;

    let yield_now = poll_fn(|cx| {
        if yielded {
            return Poll::Ready(());
        }
        yielded = true;
        cx.waker().wake_by_ref();
        Poll::Pending
    });

    yield_now.await;
}