accio_rs 0.1.2

macros for sync and async runtime
Documentation

#[macro_export]
macro_rules! acciof {
    ($y:ty,$z:ty,$c:ident) => {
        $crate::acciof!(AccioF,$y,$z,$c)
    };
    ($x:ident,$y:ty,$z:ty,$c:ident) => {
        #[repr(C)]
        struct $x {
            req: $y,
            st: i8,
            resp: Option<$z>,
            wk: Option<std::task::Waker>,
        }
        impl $x {
            fn new(r: $y) -> Self {
                Self {
                    req: r,
                    st: 0,
                    resp: None,
                    wk: None,
                }
            }
        }
        unsafe impl Send for $x {}
        unsafe impl Sync for $x {}
        impl futures::Future for $x {
            type Output = Option<$z>;
            fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
                let f = self.get_mut();
                match f.st {
                    0 => {
                        let wk = cx.waker().clone();
                        f.wk = Some(wk);
                        f.st = 1;
                        #[allow(unused_unsafe)]
                        unsafe { $c(&f.req as *const _ as *const (), &f.req as *const _ as *const (), f as *mut _ as *const _); };
                    },
                    1 => {},
                    2 => { return std::task::Poll::Ready(f.resp.take()); },
                    _ => { panic!("not ok")},
                }
                return std::task::Poll::Pending;
            }
        }
    }
}

#[macro_export]
macro_rules! acciob {
    ($x:ident,$p:ty,$q:ty,$c:ident) => {
        #[no_mangle]
        pub unsafe extern "C" fn $c(rsp: $q, resp: *const ()) {
            let resp = resp as *mut () as *mut $x;
            let x: $p = rsp.into();
            let resp = unsafe { &mut *resp};
            resp.resp = Some(x);
            resp.st = 2;
            if let Some(wk) = resp.wk.take() {
                wk.wake();
            }
        }
    };
}

#[macro_export]
macro_rules! accioe {
    ($r:ident,$y:ty,$z:ty,$q:ty,$c:ident,$b:ident)
    => 
    {
        {
            let r: $y = $r.into();
            $crate::acciof!($y,$z,$c);
            $crate::acciob!(AccioF,$z,$q,$b);
            let f = AccioF::new(r);
            let ret = f.await;
            ret
        }
    }
}