safe_migrate/report/
reporter.rs1use crate::analysis::state::Confidence;
3use crate::report::violations::{Violation, ViolationTier};
4
5pub struct Reporter;
6
7impl Reporter {
8 pub fn print_report(violations: &[Violation], confidence: &Confidence) -> bool {
9 let mut tier1 = 0;
10 let mut tier2 = 0;
11 let mut tier3 = 0;
12 let mut has_tier1_failures = false;
13
14 if violations.is_empty() {
15 println!("No schema locks or violations detected.");
16 return false;
17 }
18
19 println!("{:-<80}", "");
20
21 for v in violations {
22 let indent = " ";
24 let clean_recipe = v
25 .recipe
26 .lines()
27 .map(|line| line.trim())
28 .collect::<Vec<_>>()
29 .join(&format!("\n{}", indent));
30
31 match v.tier {
32 ViolationTier::Tier1 => {
33 tier1 += 1;
34 has_tier1_failures = true;
35 println!("[ HALT ] {}", v.title);
36 }
37 ViolationTier::Tier2 => {
38 tier2 += 1;
39 println!("[ WARN ] {}", v.title);
40 }
41 ViolationTier::Tier3 => {
42 tier3 += 1;
43 println!("[ SAFE ] {}", v.title);
44 }
45 }
46
47 println!("{}Rule: {}", indent, v.rule_id);
48 println!("{}Recipe: {}", indent, clean_recipe);
49
50 println!("{:-<80}", "");
51 }
52
53 println!();
54 println!("==================================================");
55 println!("Analysis Complete");
56 println!("==================================================");
57
58 let conf_str = match confidence {
59 Confidence::Exact => "Exact",
60 Confidence::Tainted => "Tainted (Dynamic/Opaque SQL)",
61 };
62
63 println!("Confidence: {}", conf_str);
64 println!("--------------------------------------------------");
65 println!("[ HALT ] Tier 1: {}", tier1);
66 println!("[ WARN ] Tier 2: {}", tier2);
67 println!("[ SAFE ] Tier 3: {}", tier3);
68 println!("==================================================");
69
70 has_tier1_failures
71 }
72}