use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum PolicyAction {
Allow,
AllowWithWarning {
message: String,
},
Quarantine {
reason: String,
},
Block {
reason: String,
},
RequireManualReview,
}
impl PolicyAction {
pub fn allow() -> Self {
Self::Allow
}
pub fn allow_with_warning(message: impl Into<String>) -> Self {
Self::AllowWithWarning {
message: message.into(),
}
}
pub fn quarantine(reason: impl Into<String>) -> Self {
Self::Quarantine {
reason: reason.into(),
}
}
pub fn block(reason: impl Into<String>) -> Self {
Self::Block {
reason: reason.into(),
}
}
pub fn require_review() -> Self {
Self::RequireManualReview
}
pub fn is_allowed(&self) -> bool {
matches!(self, Self::Allow | Self::AllowWithWarning { .. })
}
pub fn is_blocked(&self) -> bool {
matches!(self, Self::Block { .. })
}
pub fn is_quarantine(&self) -> bool {
matches!(self, Self::Quarantine { .. })
}
pub fn requires_review(&self) -> bool {
matches!(self, Self::RequireManualReview)
}
pub fn severity(&self) -> u8 {
match self {
Self::Allow => 0,
Self::AllowWithWarning { .. } => 1,
Self::RequireManualReview => 2,
Self::Quarantine { .. } => 3,
Self::Block { .. } => 4,
}
}
}
impl Default for PolicyAction {
fn default() -> Self {
Self::Allow
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_policy_action_helpers() {
assert!(PolicyAction::allow().is_allowed());
assert!(PolicyAction::allow_with_warning("test").is_allowed());
assert!(PolicyAction::block("malware").is_blocked());
assert!(PolicyAction::quarantine("suspicious").is_quarantine());
assert!(PolicyAction::require_review().requires_review());
}
#[test]
fn test_policy_action_severity() {
assert!(PolicyAction::Block { reason: "".into() }.severity()
> PolicyAction::Quarantine { reason: "".into() }.severity());
assert!(PolicyAction::Quarantine { reason: "".into() }.severity()
> PolicyAction::Allow.severity());
}
}