hibana 0.9.3

Session-typed choreographic programming for no_std Rust protocols, inspired by affine MPST
Documentation
use super::lane_port;
use crate::global::typestate::{RecvMeta, StateIndex};

pub(crate) struct MatchedRecvFrame<'a> {
    pub(super) desc: RecvDescriptor,
    pub(super) frame: lane_port::ReceivedFrame<'a>,
}

#[derive(Clone, Copy)]
pub(in crate::endpoint::kernel::recv) struct RecvCandidate {
    pub(in crate::endpoint::kernel::recv) desc: RecvDescriptor,
}

#[derive(Clone, Copy)]
pub(in crate::endpoint::kernel::recv) struct RecvDescriptor {
    pub(in crate::endpoint::kernel::recv) meta: RecvMeta,
    pub(in crate::endpoint::kernel::recv) cursor_index: StateIndex,
    pub(in crate::endpoint::kernel::recv) lane_idx: usize,
    pub(in crate::endpoint::kernel::recv) lane_wire: u8,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub(in crate::endpoint::kernel::recv) struct ObservedInboundKey {
    session_raw: u32,
    lane_wire: u8,
    source_role: u8,
    target_role: u8,
    frame_label: u8,
}

#[derive(Clone, Copy)]
pub(in crate::endpoint::kernel::recv) enum MatchAccumulator {
    None,
    One(RecvCandidate),
    Ambiguous,
}

#[derive(Clone, Copy)]
pub(in crate::endpoint::kernel::recv) enum MatchOutcome {
    None,
    Ambiguous,
}

impl ObservedInboundKey {
    #[inline]
    pub(in crate::endpoint::kernel::recv) fn from_frame<const ROLE: u8>(
        sid_raw: u32,
        frame: &lane_port::PreambleFrame<'_>,
    ) -> Self {
        let observation = frame.observed_transport_frame(sid_raw, frame.lane_wire(), ROLE);
        Self {
            session_raw: observation.session_raw(),
            lane_wire: observation.lane_wire(),
            source_role: observation.source_role(),
            target_role: observation.target_role(),
            frame_label: observation.label_raw(),
        }
    }

    #[inline]
    pub(in crate::endpoint::kernel::recv) const fn matches_recv_meta(
        self,
        sid_raw: u32,
        lane_wire: u8,
        local_role: u8,
        meta: RecvMeta,
    ) -> bool {
        self.session_raw == sid_raw
            && self.lane_wire == lane_wire
            && self.source_role == meta.peer
            && self.target_role == local_role
            && self.frame_label == meta.frame_label
    }
}

impl MatchAccumulator {
    #[inline]
    pub(in crate::endpoint::kernel::recv) const fn add(self, candidate: RecvCandidate) -> Self {
        match self {
            MatchAccumulator::None => MatchAccumulator::One(candidate),
            MatchAccumulator::One(_) | MatchAccumulator::Ambiguous => MatchAccumulator::Ambiguous,
        }
    }

    #[inline]
    pub(in crate::endpoint::kernel::recv) const fn finish(
        self,
    ) -> Result<RecvCandidate, MatchOutcome> {
        match self {
            MatchAccumulator::None => Err(MatchOutcome::None),
            MatchAccumulator::One(candidate) => Ok(candidate),
            MatchAccumulator::Ambiguous => Err(MatchOutcome::Ambiguous),
        }
    }
}