hibana 0.9.6

Choreography-derived runtime enforcement kernel for no_std Rust multiparty protocols
Documentation
use super::{FrontierProgressCandidate, LaneOfferState, OfferEntryObservedState};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct OfferEntryEvidence {
    bits: u8,
}

impl OfferEntryEvidence {
    pub(crate) const FLAG_READY_ARM: u8 = 1;
    pub(crate) const FLAG_INGRESS_READY: u8 = 1 << 1;

    #[inline]
    pub(crate) const fn empty() -> Self {
        Self { bits: 0 }
    }

    #[inline]
    pub(crate) const fn with_ready_arm(self) -> Self {
        Self {
            bits: self.bits | Self::FLAG_READY_ARM,
        }
    }

    #[inline]
    pub(crate) const fn with_ingress_ready(self) -> Self {
        Self {
            bits: self.bits | Self::FLAG_INGRESS_READY,
        }
    }

    #[inline]
    pub(crate) const fn has_ready_arm(self) -> bool {
        (self.bits & Self::FLAG_READY_ARM) != 0
    }

    #[inline]
    pub(crate) const fn ingress_ready(self) -> bool {
        (self.bits & Self::FLAG_INGRESS_READY) != 0
    }
}

#[inline]
pub(crate) fn candidate_has_progress_evidence(evidence: OfferEntryEvidence) -> bool {
    evidence.has_ready_arm() || evidence.ingress_ready()
}

#[inline]
pub(crate) fn offer_entry_observed_state(
    info: LaneOfferState,
    evidence: OfferEntryEvidence,
) -> OfferEntryObservedState {
    let has_progress_evidence = candidate_has_progress_evidence(evidence);
    let ready = has_progress_evidence || info.intrinsic_ready();
    let mut flags = 0u8;
    if info.is_controller() {
        flags |= OfferEntryObservedState::FLAG_CONTROLLER;
    }
    if info.is_dynamic() {
        flags |= OfferEntryObservedState::FLAG_DYNAMIC;
    }
    if has_progress_evidence {
        flags |= OfferEntryObservedState::FLAG_PROGRESS;
    }
    if evidence.has_ready_arm() {
        flags |= OfferEntryObservedState::FLAG_READY_ARM;
    }
    if ready {
        flags |= OfferEntryObservedState::FLAG_READY;
    }
    OfferEntryObservedState {
        key: crate::invariant_some(info.key()),
        frontier_mask: info.frontier.bit(),
        flags,
    }
}

#[inline]
pub(crate) fn offer_entry_frontier_progress_candidate(
    info: LaneOfferState,
    observed: OfferEntryObservedState,
) -> Option<FrontierProgressCandidate> {
    if Some(observed.key) != info.key() {
        crate::invariant();
    }
    if !observed.has_progress_evidence() {
        return None;
    }
    if !observed.is_ready() {
        crate::invariant();
    }
    Some(FrontierProgressCandidate {
        scope_id: info.scope,
        entry: observed.key.entry(),
        parallel_root: info.parallel_root,
        frontier: info.frontier,
    })
}

#[cfg(kani)]
mod kani;