allow-core 0.1.11

Core types and matching primitives for cargo-allow source exception policies.
Documentation
use crate::{CargoAllowError, FindingKind};
use std::collections::BTreeMap;
use std::str::FromStr;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub enum LaneEnforcementMode {
    Advisory,
    Shadow,
    #[default]
    Blocking,
}

impl LaneEnforcementMode {
    pub const ALL: &[Self] = &[Self::Advisory, Self::Shadow, Self::Blocking];

    pub fn as_str(self) -> &'static str {
        match self {
            Self::Advisory => "advisory",
            Self::Shadow => "shadow",
            Self::Blocking => "blocking",
        }
    }

    pub fn blocks_check_failure(self) -> bool {
        matches!(self, Self::Blocking)
    }
}

impl FromStr for LaneEnforcementMode {
    type Err = CargoAllowError;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        match value.trim() {
            "advisory" => Ok(Self::Advisory),
            "shadow" => Ok(Self::Shadow),
            "blocking" => Ok(Self::Blocking),
            other => Err(CargoAllowError::new(format!(
                "unsupported lane enforcement mode `{other}`"
            ))),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LaneConfig {
    pub mode: LaneEnforcementMode,
}

pub fn lane_enforcement_mode_for_kind(
    lanes: &BTreeMap<String, LaneConfig>,
    kind: FindingKind,
) -> LaneEnforcementMode {
    lanes
        .get(kind.as_str())
        .map(|lane| lane.mode)
        .unwrap_or(LaneEnforcementMode::Blocking)
}

pub fn effective_lane_posture_for_findings(
    lanes: &BTreeMap<String, LaneConfig>,
    kinds: impl IntoIterator<Item = FindingKind>,
) -> BTreeMap<String, LaneEnforcementMode> {
    let mut effective = lanes
        .iter()
        .map(|(name, lane)| (name.clone(), lane.mode))
        .collect::<BTreeMap<_, _>>();
    for kind in kinds {
        effective
            .entry(kind.as_str().to_string())
            .or_insert(LaneEnforcementMode::Blocking);
    }
    effective
}

#[cfg(test)]
#[path = "lane_posture_tests.rs"]
mod tests;