cu_profiler_core/budget/
result.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "lowercase")]
8pub enum PolicyStatus {
9 Pass,
11 Warn,
13 Fail,
15}
16
17impl PolicyStatus {
18 #[must_use]
20 pub fn label(self) -> &'static str {
21 match self {
22 Self::Pass => "PASS",
23 Self::Warn => "WARN",
24 Self::Fail => "FAIL",
25 }
26 }
27
28 #[must_use]
30 pub fn max(self, other: Self) -> Self {
31 self.max_rank(other)
32 }
33
34 fn rank(self) -> u8 {
35 match self {
36 Self::Pass => 0,
37 Self::Warn => 1,
38 Self::Fail => 2,
39 }
40 }
41
42 fn max_rank(self, other: Self) -> Self {
43 if self.rank() >= other.rank() {
44 self
45 } else {
46 other
47 }
48 }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
54#[serde(rename_all = "lowercase")]
55pub enum Severity {
56 Info,
58 Warning,
60 Error,
62}
63
64#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
66pub struct PolicyResult {
67 pub policy_id: String,
69 pub status: PolicyStatus,
71 pub severity: Severity,
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub actual: Option<f64>,
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub expected: Option<f64>,
79 pub message: String,
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub remediation: Option<String>,
84}
85
86impl PolicyResult {
87 #[must_use]
89 pub fn pass(policy_id: impl Into<String>, message: impl Into<String>) -> Self {
90 Self {
91 policy_id: policy_id.into(),
92 status: PolicyStatus::Pass,
93 severity: Severity::Info,
94 actual: None,
95 expected: None,
96 message: message.into(),
97 remediation: None,
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn status_max_picks_worst() {
108 assert_eq!(
109 PolicyStatus::Pass.max(PolicyStatus::Fail),
110 PolicyStatus::Fail
111 );
112 assert_eq!(
113 PolicyStatus::Warn.max(PolicyStatus::Pass),
114 PolicyStatus::Warn
115 );
116 }
117}