1use serde::Serialize;
2use std::fmt;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
6#[serde(rename_all = "snake_case")]
7pub enum RuleId {
8 UndefinedVariable,
10 UndefinedGlobal,
12 UndefinedField,
14 UnusedVariable,
16}
17
18impl fmt::Display for RuleId {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 Self::UndefinedVariable => write!(f, "undefined-variable"),
22 Self::UndefinedGlobal => write!(f, "undefined-global"),
23 Self::UndefinedField => write!(f, "undefined-field"),
24 Self::UnusedVariable => write!(f, "unused-variable"),
25 }
26 }
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
31#[serde(rename_all = "lowercase")]
32pub enum Severity {
33 Error,
34 Warning,
35 Info,
36}
37
38#[derive(Debug, Clone, Serialize)]
40pub struct Diagnostic {
41 pub rule: RuleId,
42 pub severity: Severity,
43 pub message: String,
44 pub line: usize,
45 pub column: usize,
46}
47
48#[derive(Debug, Clone, Serialize)]
50pub struct LintResult {
51 pub diagnostics: Vec<Diagnostic>,
52 pub error_count: usize,
53 pub warning_count: usize,
54}
55
56impl LintResult {
57 pub fn new(diagnostics: Vec<Diagnostic>) -> Self {
58 let error_count = diagnostics
59 .iter()
60 .filter(|d| d.severity == Severity::Error)
61 .count();
62 let warning_count = diagnostics
63 .iter()
64 .filter(|d| d.severity == Severity::Warning)
65 .count();
66 Self {
67 diagnostics,
68 error_count,
69 warning_count,
70 }
71 }
72
73 pub fn has_errors(&self) -> bool {
75 self.error_count > 0
76 }
77}