use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "level", rename_all = "snake_case")]
pub enum Destructiveness {
Safe,
RequiresApproval {
reason: String,
},
RequiresApprovalAndDataLossWarning {
reason: String,
},
}
impl Destructiveness {
pub const fn requires_approval(&self) -> bool {
!matches!(self, Self::Safe)
}
pub const fn data_loss_risk(&self) -> bool {
matches!(self, Self::RequiresApprovalAndDataLossWarning { .. })
}
pub const fn reason(&self) -> Option<&str> {
match self {
Self::Safe => None,
Self::RequiresApproval { reason }
| Self::RequiresApprovalAndDataLossWarning { reason } => Some(reason.as_str()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn safe_does_not_require_approval() {
let d = Destructiveness::Safe;
assert!(!d.requires_approval());
assert!(!d.data_loss_risk());
assert_eq!(d.reason(), None);
}
#[test]
fn requires_approval_flags_approval_only() {
let d = Destructiveness::RequiresApproval {
reason: "drops index".into(),
};
assert!(d.requires_approval());
assert!(!d.data_loss_risk());
assert_eq!(d.reason(), Some("drops index"));
}
#[test]
fn data_loss_warning_flags_both() {
let d = Destructiveness::RequiresApprovalAndDataLossWarning {
reason: "drops column email".into(),
};
assert!(d.requires_approval());
assert!(d.data_loss_risk());
assert_eq!(d.reason(), Some("drops column email"));
}
#[test]
fn serde_round_trip_safe() {
let d = Destructiveness::Safe;
let json = serde_json::to_string(&d).unwrap();
assert_eq!(json, r#"{"level":"safe"}"#);
let back: Destructiveness = serde_json::from_str(&json).unwrap();
assert_eq!(d, back);
}
#[test]
fn serde_round_trip_requires_approval() {
let d = Destructiveness::RequiresApproval { reason: "x".into() };
let json = serde_json::to_string(&d).unwrap();
let back: Destructiveness = serde_json::from_str(&json).unwrap();
assert_eq!(d, back);
}
#[test]
fn serde_round_trip_data_loss() {
let d = Destructiveness::RequiresApprovalAndDataLossWarning { reason: "x".into() };
let json = serde_json::to_string(&d).unwrap();
let back: Destructiveness = serde_json::from_str(&json).unwrap();
assert_eq!(d, back);
}
}