Skip to main content

safe_migrate/report/
reporter.rs

1// FILE: src/report/reporter.rs
2use 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            // Indent by exactly 9 spaces to align under the 8-character tags + 1 space
23            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}