anni_common/
lint.rs

1use crate::diagnostic::{Diagnostic, DiagnosticSeverity};
2use serde::Serialize;
3
4pub trait AnniLinter<T> {
5    fn add(&mut self, msg: Diagnostic<T>);
6    fn flush(&self) -> bool;
7}
8
9#[derive(Default)]
10pub struct AnniLinterReviewDogJsonLineFormat(bool);
11
12impl AnniLinterReviewDogJsonLineFormat {
13    pub fn new() -> Self {
14        AnniLinterReviewDogJsonLineFormat(false)
15    }
16}
17
18impl<T: Serialize> AnniLinter<T> for AnniLinterReviewDogJsonLineFormat {
19    fn add(&mut self, msg: Diagnostic<T>) {
20        if let DiagnosticSeverity::Error = msg.severity {
21            self.0 = true;
22        }
23        println!("{}", serde_json::to_string(&msg).unwrap());
24    }
25
26    fn flush(&self) -> bool {
27        !self.0
28    }
29}
30
31pub struct AnniLinterTextFormat<T> {
32    errors: Vec<Diagnostic<T>>,
33    warnings: Vec<Diagnostic<T>>,
34}
35
36impl<T> Default for AnniLinterTextFormat<T> {
37    fn default() -> Self {
38        Self {
39            errors: Vec::new(),
40            warnings: Vec::new(),
41        }
42    }
43}
44
45impl<T> AnniLinter<T> for AnniLinterTextFormat<T> {
46    fn add(&mut self, msg: Diagnostic<T>) {
47        match msg.severity {
48            DiagnosticSeverity::Error => self.errors.push(msg),
49            DiagnosticSeverity::Warning => self.warnings.push(msg),
50            _ => {}
51        }
52    }
53
54    fn flush(&self) -> bool {
55        println!(
56            "{} errors, {} warnings",
57            self.errors.len(),
58            self.warnings.len()
59        );
60        println!();
61        for error in self.errors.iter() {
62            println!(
63                "[ERROR][{}] {}:{}: {}",
64                error.location.path,
65                error.location.start_line(),
66                error.location.start_column().unwrap_or(0),
67                error.message.message
68            );
69        }
70        println!();
71        for warn in self.warnings.iter() {
72            println!(
73                "[WARN][{}] {}:{}: {}",
74                warn.location.path,
75                warn.location.start_line(),
76                warn.location.start_column().unwrap_or(0),
77                warn.message.message
78            );
79        }
80
81        self.errors.is_empty()
82    }
83}