Skip to main content

allow_core/
lane_posture.rs

1use crate::{CargoAllowError, FindingKind};
2use std::collections::BTreeMap;
3use std::str::FromStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
6pub enum LaneEnforcementMode {
7    Advisory,
8    Shadow,
9    #[default]
10    Blocking,
11}
12
13impl LaneEnforcementMode {
14    pub const ALL: &[Self] = &[Self::Advisory, Self::Shadow, Self::Blocking];
15
16    pub fn as_str(self) -> &'static str {
17        match self {
18            Self::Advisory => "advisory",
19            Self::Shadow => "shadow",
20            Self::Blocking => "blocking",
21        }
22    }
23
24    pub fn blocks_check_failure(self) -> bool {
25        matches!(self, Self::Blocking)
26    }
27}
28
29impl FromStr for LaneEnforcementMode {
30    type Err = CargoAllowError;
31
32    fn from_str(value: &str) -> Result<Self, Self::Err> {
33        match value.trim() {
34            "advisory" => Ok(Self::Advisory),
35            "shadow" => Ok(Self::Shadow),
36            "blocking" => Ok(Self::Blocking),
37            other => Err(CargoAllowError::new(format!(
38                "unsupported lane enforcement mode `{other}`"
39            ))),
40        }
41    }
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct LaneConfig {
46    pub mode: LaneEnforcementMode,
47}
48
49pub fn lane_enforcement_mode_for_kind(
50    lanes: &BTreeMap<String, LaneConfig>,
51    kind: FindingKind,
52) -> LaneEnforcementMode {
53    lanes
54        .get(kind.as_str())
55        .map(|lane| lane.mode)
56        .unwrap_or(LaneEnforcementMode::Blocking)
57}
58
59pub fn effective_lane_posture_for_findings(
60    lanes: &BTreeMap<String, LaneConfig>,
61    kinds: impl IntoIterator<Item = FindingKind>,
62) -> BTreeMap<String, LaneEnforcementMode> {
63    let mut effective = lanes
64        .iter()
65        .map(|(name, lane)| (name.clone(), lane.mode))
66        .collect::<BTreeMap<_, _>>();
67    for kind in kinds {
68        effective
69            .entry(kind.as_str().to_string())
70            .or_insert(LaneEnforcementMode::Blocking);
71    }
72    effective
73}
74
75#[cfg(test)]
76#[path = "lane_posture_tests.rs"]
77mod tests;