hibana 0.9.2

Session-typed choreographic programming for no_std Rust protocols, inspired by affine MPST
Documentation
use super::{
    EffList, eff,
    scope_ranges::{
        parallel_arm_ranges_from_enter, parallel_enter_at, route_arm_ranges_from_first_enter,
        route_enter_at,
    },
};

pub(crate) const fn first_visible_controller_mask(
    eff_list: &EffList,
    start: usize,
    end: usize,
) -> u16 {
    let markers = eff_list.scope_markers();
    let mut idx = start;
    while idx < end && idx < eff_list.len() {
        if let Some(route_enter) = route_enter_at(markers, idx, end, 0) {
            let (_, arm0_start, arm0_end, _, arm1_start, arm1_end) =
                route_arm_ranges_from_first_enter(markers, route_enter);
            return first_visible_controller_mask(eff_list, arm0_start, arm0_end)
                | first_visible_controller_mask(eff_list, arm1_start, arm1_end);
        }
        if let Some(par_enter) = parallel_enter_at(markers, idx, end, 0) {
            let Some((arm0_start, arm0_end, arm1_start, arm1_end)) =
                parallel_arm_ranges_from_enter(markers, par_enter)
            else {
                return 0;
            };
            return first_visible_controller_mask(eff_list, arm0_start, arm0_end)
                | first_visible_controller_mask(eff_list, arm1_start, arm1_end);
        }

        let node = eff_list.node_at(idx);
        if matches!(node.kind, eff::EffKind::Atom) {
            let atom = node.atom_data();
            if atom.from >= crate::g::ROLE_DOMAIN_SIZE {
                return 0;
            }
            return 1u16 << atom.from;
        }
        idx += 1;
    }
    0
}