slings 0.1.4

A small async runtime based on io-uring for Rust
Documentation
use std::future::Future;
use std::io;
use std::mem;
use std::pin::Pin;
use std::task::{Context, Poll};

use io_uring::squeue::Entry;

use crate::driver::{self, Driver, State};

pub(crate) struct Action<T> {
    pub driver: Driver,
    pub action: Option<T>,
    key: u64,
}

impl<T> Action<T> {
    pub fn submit(action: T, entry: Entry) -> io::Result<Action<T>> {
        driver::CURRENT.with(|driver| {
            let key = driver.submit(entry)?;

            Ok(Action {
                driver: driver.clone(),
                action: Some(action),
                key,
            })
        })
    }
}

impl<T> Future for Action<T>
where
    T: Unpin,
{
    type Output = Completion<T>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        let me = &mut *self;
        let mut inner = me.driver.inner.borrow_mut();
        let key = me.key as usize;
        let state = mem::replace(&mut inner.actions[key], State::Submitted);

        match state {
            State::Submitted => {
                inner.actions[key] = State::Waiting(cx.waker().clone());
                Poll::Pending
            }
            State::Waiting(waker) => {
                if !waker.will_wake(cx.waker()) {
                    inner.actions[key] = State::Waiting(cx.waker().clone());
                } else {
                    inner.actions[key] = State::Waiting(waker);
                }
                Poll::Pending
            }
            State::Completed(cqe) => {
                inner.actions.remove(key);

                let result = if cqe.result() >= 0 {
                    Ok(cqe.result())
                } else {
                    Err(io::Error::from_raw_os_error(-cqe.result()))
                };
                let flags = cqe.flags();
                let action = me.action.take().expect("action can not be None");

                Poll::Ready(Completion {
                    action,
                    result,
                    flags,
                })
            }
        }
    }
}

pub(crate) struct Completion<T> {
    pub(crate) action: T,
    pub(crate) result: io::Result<i32>,
    pub(crate) flags: u32,
}