Skip to main content

allow_report/
diff_posture.rs

1use crate::{DiffFindingChange, DiffPolicyChange, DiffPostureSummary};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum DiffNetPosture {
5    Worse,
6    ReviewRequired,
7    Improved,
8    Unchanged,
9}
10
11impl DiffNetPosture {
12    pub fn as_str(self) -> &'static str {
13        match self {
14            Self::Worse => "worse",
15            Self::ReviewRequired => "review-required",
16            Self::Improved => "improved",
17            Self::Unchanged => "unchanged",
18        }
19    }
20
21    pub fn reviewer_action(self) -> &'static str {
22        match self {
23            Self::Worse => {
24                "block until failing source exception changes are fixed, narrowed, or receipted."
25            }
26            Self::ReviewRequired => "review the source exception posture change before merging.",
27            Self::Improved => "verify the cleanup was intentional and keep the narrower posture.",
28            Self::Unchanged => "no source exception posture change detected.",
29        }
30    }
31}
32
33pub fn diff_posture_summary(
34    current_failures: usize,
35    finding_changes: &[DiffFindingChange<'_>],
36    policy_changes: &[DiffPolicyChange<'_>],
37) -> DiffPostureSummary {
38    DiffPostureSummary {
39        current_failures,
40        new_findings: finding_changes
41            .iter()
42            .filter(|change| change.change == "new")
43            .count(),
44        removed_findings: finding_changes
45            .iter()
46            .filter(|change| change.change == "removed")
47            .count(),
48        policy_failures: policy_changes
49            .iter()
50            .filter(|change| change.severity == "fail")
51            .count(),
52        policy_review_items: policy_changes
53            .iter()
54            .filter(|change| change.severity == "review")
55            .count(),
56        policy_improvements: policy_changes
57            .iter()
58            .filter(|change| change.severity == "improvement")
59            .count(),
60    }
61}
62
63pub fn diff_net_posture(summary: DiffPostureSummary) -> DiffNetPosture {
64    if summary.current_failures > 0 || summary.policy_failures > 0 {
65        return DiffNetPosture::Worse;
66    }
67    if summary.new_findings > 0 || summary.policy_review_items > 0 {
68        return DiffNetPosture::ReviewRequired;
69    }
70    if summary.removed_findings > 0 || summary.policy_improvements > 0 {
71        return DiffNetPosture::Improved;
72    }
73    DiffNetPosture::Unchanged
74}