hibana 0.9.6

Choreography-derived runtime enforcement kernel for no_std Rust multiparty protocols
Documentation
use core::cell::Cell;

#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(kani, derive(kani::Arbitrary))]
pub(crate) enum RendezvousAccessState {
    Available = 0,
    RegistryLease = 1,
    ScratchLease = 2,
    EndpointOperation = 3,
    EndpointScratchLease = 4,
}

impl RendezvousAccessState {
    #[inline]
    pub(crate) const fn begin_endpoint_operation(self) -> Option<Self> {
        match self {
            Self::Available => Some(Self::EndpointOperation),
            Self::RegistryLease
            | Self::ScratchLease
            | Self::EndpointOperation
            | Self::EndpointScratchLease => None,
        }
    }

    #[inline]
    pub(crate) const fn finish_endpoint_operation(self) -> Option<Self> {
        match self {
            Self::EndpointOperation => Some(Self::Available),
            Self::Available
            | Self::RegistryLease
            | Self::ScratchLease
            | Self::EndpointScratchLease => None,
        }
    }

    #[inline]
    pub(crate) const fn begin_scratch(self) -> Option<(Self, Self)> {
        match self {
            Self::Available => Some((Self::ScratchLease, Self::Available)),
            Self::EndpointOperation => Some((Self::EndpointScratchLease, Self::EndpointOperation)),
            Self::RegistryLease | Self::ScratchLease | Self::EndpointScratchLease => None,
        }
    }

    #[inline]
    pub(crate) const fn finish_scratch(self) -> Option<Self> {
        match self {
            Self::ScratchLease => Some(Self::Available),
            Self::EndpointScratchLease => Some(Self::EndpointOperation),
            Self::Available | Self::RegistryLease | Self::EndpointOperation => None,
        }
    }
}

pub(crate) struct EndpointOperationLease<'r> {
    state: &'r Cell<RendezvousAccessState>,
}

impl<'r> EndpointOperationLease<'r> {
    pub(super) const fn new(state: &'r Cell<RendezvousAccessState>) -> Self {
        Self { state }
    }
}

impl Drop for EndpointOperationLease<'_> {
    #[inline]
    fn drop(&mut self) {
        let next = crate::invariant_some(self.state.get().finish_endpoint_operation());
        self.state.set(next);
    }
}