sark-core 0.29.5

Fiber-free request, route, dispatch, and lifecycle core for Sark
use dope_core::driver::schedule::ready;

#[must_use = "admission exhaustion must re-arm the exact connection owner"]
#[derive(Clone, Copy, Default, PartialEq, Eq)]
pub struct Progress(State);

#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(u8)]
enum State {
    #[default]
    Idle,
    Drained,
    Exhausted,
    Both,
}

impl Progress {
    pub const fn has_drained(self) -> bool {
        matches!(self.0, State::Drained | State::Both)
    }

    pub const fn is_exhausted(self) -> bool {
        matches!(self.0, State::Exhausted | State::Both)
    }

    pub fn error<E>(result: Result<Self, E>, wake: ready::Target<'_>) -> Option<E> {
        match result {
            Ok(progress) => {
                if progress.is_exhausted() {
                    wake.wake();
                }
                None
            }
            Err(error) => Some(error),
        }
    }

    pub(crate) fn exhaust(&mut self) {
        self.0 = match self.0 {
            State::Idle | State::Exhausted => State::Exhausted,
            State::Drained | State::Both => State::Both,
        };
    }

    pub(crate) fn record(&mut self) {
        self.0 = match self.0 {
            State::Idle | State::Drained => State::Drained,
            State::Exhausted | State::Both => State::Both,
        };
    }

    pub fn merge(&mut self, other: Self) {
        match other.0 {
            State::Idle => {}
            State::Drained => self.record(),
            State::Exhausted => self.exhaust(),
            State::Both => self.0 = State::Both,
        }
    }
}

const _: () = {
    assert!(core::mem::size_of::<Progress>() == 1);
    assert!(core::mem::align_of::<Progress>() == 1);
};