azur 0.3.1

A no_std Rust crate that implements an executor/reactor and futures using io_uring
Documentation
use core::{
    future::Future,
    marker::PhantomData,
};

use tracing::error;

use crate::reactor::{
    Reactor,
    REACTOR,
};

pub struct Scope<'scope, 'env: 'scope> {
    // Ensure contravariance over `'scope'`.
    _scope: PhantomData<fn(&'scope ())>,
    // Ensure covariance over `'env`.
    _env: PhantomData<&'env ()>,
}

impl<'scope, 'env> Scope<'scope, 'env> {
    pub fn spawn<F>(&self, future: F)
    where
        F: Future<Output = ()> + 'scope,
    {
        unsafe { Reactor::spawn_unchecked(&REACTOR, future) };
    }
}

pub fn scope<'env, F, T>(f: F) -> T
where
    F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> T,
{
    let ret = f(&Scope {
        _scope: PhantomData,
        _env: PhantomData,
    });
    if let Err(err) = crate::run() {
        error!("failed to run in scope: {err}");
        crate::freeze();
    }
    ret
}

#[cfg(test)]
mod tests {
    use core::cell::RefCell;

    use crate::DelayType;

    #[test]
    fn scoped() {
        let done = RefCell::new(false);
        super::scope(|scope| {
            scope.spawn(async {
                crate::delay(
                    lx::timespec {
                        tv_sec: 0,
                        tv_nsec: 1_000_000 * 200,
                    },
                    DelayType::Relative,
                )
                .await
                .unwrap();
                *done.borrow_mut() = true;
            });
        });
        assert!(*done.borrow());
    }
}