dope-sys 0.23.0

Typed operating-system call contracts
Documentation
use std::{array, cell::Cell, convert::Infallible, ops::ControlFlow, task, time};

use dope_sys::{
    engine,
    engine::life::{Reclaim, Resolver, Step},
    io::reactor::ready::store::Quota,
    probe::Stopped,
};

#[derive(Debug)]
pub struct Batch {
    pub(crate) entries: array::IntoIter<Result<(), u16>, 3>,
    pub(crate) reports: Vec<u16>,
    pub(crate) reads: usize,
    pub(crate) calls: Cell<usize>,
}

impl engine::raw::Poll for Batch {
    type Context = ();
    type Error = Infallible;

    unsafe fn commit<'a, Q: Quota>(
        &'a mut self,
        _quota: Q,
        _defer: impl FnOnce() -> bool,
    ) -> Result<task::Poll<()>, Self::Error>
    where
        Self::Context: 'a,
    {
        self.calls.set(self.calls.get() + 1);
        Ok(task::Poll::Ready(()))
    }

    unsafe fn wait<'a, Q: Quota>(
        &'a mut self,
        _quota: Q,
        _timeout: Option<time::Duration>,
        _busy: impl FnOnce() -> bool,
    ) -> Result<(), Self::Error>
    where
        Self::Context: 'a,
    {
        self.calls.set(self.calls.get() + 1);
        Ok(())
    }
}
impl Resolver for Batch {
    type Backend = Self;
    type Fault = u16;

    fn backend(&mut self) -> &mut Self {
        self.calls.set(self.calls.get() + 1);
        self
    }

    fn retire_one(&mut self) -> Step {
        self.calls.set(self.calls.get() + 1);
        Step::Empty
    }

    fn has_pending(&self) -> bool {
        self.calls.set(self.calls.get() + 1);
        false
    }

    fn has_flights(&self) -> bool {
        self.calls.set(self.calls.get() + 1);
        false
    }

    fn has_inflight(&self) -> bool {
        self.calls.set(self.calls.get() + 1);
        false
    }
}

impl Reclaim for Batch {
    fn reclaim(mut self) -> Result<ControlFlow<Self, Self>, Stopped<Self, u16>> {
        self.reads += 1;
        match self.entries.next() {
            Some(Ok(())) => Ok(ControlFlow::Continue(self)),
            Some(Err(cause)) => Err(Stopped { state: self, cause }),
            None => Ok(ControlFlow::Break(self)),
        }
    }

    fn fault(mut failure: Stopped<Self, u16>) -> Self {
        failure.state.reports.push(failure.cause);
        failure.state
    }

    fn reactor(&mut self, failure: Infallible) {
        match failure {}
    }
}