aiur 0.0.8

Single threaded async executor with structured concurrency
Documentation
//  \ O /
//  / * \    aiur: the homeplanet for the famous executors
// |' | '|   (c) 2020 - present, Vladimir Zvezda
//   / \
use std::time::Duration;

// Use the toy runtime
use aiur::toy_rt::{self};

// With emulated sleep test run instantly, actual sleep actually wait for specified
// amount of time.
//const SLEEP_MODE: toy_rt::SleepMode = toy_rt::SleepMode::Actual;
const SLEEP_MODE: toy_rt::SleepMode = toy_rt::SleepMode::Emulated;

// drop() impl for this truct is blocked until drop_async().await is completed.
struct WaitOnDrop<'rt> {
    rt: &'rt toy_rt::Runtime,
    drop_length: Duration,
}

impl<'rt> WaitOnDrop<'rt> {
    fn new_onesec(rt: &'rt toy_rt::Runtime) -> Self {
        Self::new(rt, Duration::from_millis(1000))
    }

    fn new(rt: &'rt toy_rt::Runtime, drop_length: Duration) -> Self {
        Self { rt, drop_length }
    }

    // a helper function to invoke from Drop::drop()
    async fn drop_async(&self) {
        toy_rt::sleep(self.rt, self.drop_length).await;
    }
}

impl<'rt> Drop for WaitOnDrop<'rt> {
    fn drop(&mut self) {
        self.rt.nested_loop(self.drop_async());
    }
}

// Just makes sure that async destruction is feasible. When there is only one task
// there is no much to test, check out other tests with several tasks and frozen events.
#[test]
fn async_drop_proof() {
    async fn measured(rt: &toy_rt::Runtime) {
        let _long_drop = WaitOnDrop::new_onesec(rt);
        // Here invokes the drop(_long_drop) that 
    }

    async fn async_starter(rt: &toy_rt::Runtime, _: ()) {
        let start = rt.io().now32();
        measured(rt).await;
        let elapsed = rt.io().now32() - start;
        assert!(elapsed >= 1 * 1000);
        assert!(elapsed < 2 * 1000);
    }

    toy_rt::with_runtime_in_mode(SLEEP_MODE, async_starter, ());
}