pgevolve_core/diff/
destructiveness.rs1use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(tag = "level", rename_all = "snake_case")]
12pub enum Destructiveness {
13 Safe,
15 RequiresApproval {
17 reason: String,
19 },
20 RequiresApprovalAndDataLossWarning {
22 reason: String,
24 },
25}
26
27impl Destructiveness {
28 pub const fn requires_approval(&self) -> bool {
30 !matches!(self, Self::Safe)
31 }
32
33 pub const fn data_loss_risk(&self) -> bool {
35 matches!(self, Self::RequiresApprovalAndDataLossWarning { .. })
36 }
37
38 pub const fn reason(&self) -> Option<&str> {
40 match self {
41 Self::Safe => None,
42 Self::RequiresApproval { reason }
43 | Self::RequiresApprovalAndDataLossWarning { reason } => Some(reason.as_str()),
44 }
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn safe_does_not_require_approval() {
54 let d = Destructiveness::Safe;
55 assert!(!d.requires_approval());
56 assert!(!d.data_loss_risk());
57 assert_eq!(d.reason(), None);
58 }
59
60 #[test]
61 fn requires_approval_flags_approval_only() {
62 let d = Destructiveness::RequiresApproval {
63 reason: "drops index".into(),
64 };
65 assert!(d.requires_approval());
66 assert!(!d.data_loss_risk());
67 assert_eq!(d.reason(), Some("drops index"));
68 }
69
70 #[test]
71 fn data_loss_warning_flags_both() {
72 let d = Destructiveness::RequiresApprovalAndDataLossWarning {
73 reason: "drops column email".into(),
74 };
75 assert!(d.requires_approval());
76 assert!(d.data_loss_risk());
77 assert_eq!(d.reason(), Some("drops column email"));
78 }
79
80 #[test]
81 fn serde_round_trip_safe() {
82 let d = Destructiveness::Safe;
83 let json = serde_json::to_string(&d).unwrap();
84 assert_eq!(json, r#"{"level":"safe"}"#);
85 let back: Destructiveness = serde_json::from_str(&json).unwrap();
86 assert_eq!(d, back);
87 }
88
89 #[test]
90 fn serde_round_trip_requires_approval() {
91 let d = Destructiveness::RequiresApproval { reason: "x".into() };
92 let json = serde_json::to_string(&d).unwrap();
93 let back: Destructiveness = serde_json::from_str(&json).unwrap();
94 assert_eq!(d, back);
95 }
96
97 #[test]
98 fn serde_round_trip_data_loss() {
99 let d = Destructiveness::RequiresApprovalAndDataLossWarning { reason: "x".into() };
100 let json = serde_json::to_string(&d).unwrap();
101 let back: Destructiveness = serde_json::from_str(&json).unwrap();
102 assert_eq!(d, back);
103 }
104}