1use std::borrow::Cow;
2
3use miette::SourceSpan;
4use nu_protocol::Span;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
7pub enum Severity {
8 Error,
9 Warning,
10 Info,
11}
12
13impl std::fmt::Display for Severity {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 match self {
16 Severity::Error => write!(f, "error"),
17 Severity::Warning => write!(f, "warning"),
18 Severity::Info => write!(f, "info"),
19 }
20 }
21}
22
23#[derive(Debug, Clone)]
24pub struct Violation {
25 pub rule_id: Cow<'static, str>,
26 pub severity: Severity,
27 pub message: Cow<'static, str>,
28 pub span: Span,
29 pub suggestion: Option<Cow<'static, str>>,
30 pub fix: Option<Fix>,
31 pub file: Option<Cow<'static, str>>,
32}
33
34impl Violation {
35 #[must_use]
37 pub const fn new_static(
38 rule_id: &'static str,
39 severity: Severity,
40 message: &'static str,
41 span: Span,
42 ) -> Self {
43 Self {
44 rule_id: Cow::Borrowed(rule_id),
45 severity,
46 message: Cow::Borrowed(message),
47 span,
48 suggestion: None,
49 fix: None,
50 file: None,
51 }
52 }
53
54 #[must_use]
56 pub fn new_dynamic(
57 rule_id: &'static str,
58 severity: Severity,
59 message: String,
60 span: Span,
61 ) -> Self {
62 Self {
63 rule_id: Cow::Borrowed(rule_id),
64 severity,
65 message: Cow::Owned(message),
66 span,
67 suggestion: None,
68 fix: None,
69 file: None,
70 }
71 }
72
73 #[must_use]
75 pub fn with_suggestion_static(mut self, suggestion: &'static str) -> Self {
76 self.suggestion = Some(Cow::Borrowed(suggestion));
77 self
78 }
79
80 #[must_use]
82 pub fn with_suggestion_dynamic(mut self, suggestion: String) -> Self {
83 self.suggestion = Some(Cow::Owned(suggestion));
84 self
85 }
86
87 #[must_use]
89 pub fn with_fix(mut self, fix: Fix) -> Self {
90 self.fix = Some(fix);
91 self
92 }
93
94 #[must_use]
95 pub fn to_source_span(&self) -> SourceSpan {
96 SourceSpan::from((self.span.start, self.span.end - self.span.start))
97 }
98}
99
100#[derive(Debug, Clone)]
101pub struct Fix {
102 pub description: Cow<'static, str>,
103 pub replacements: Vec<Replacement>,
104}
105
106impl Fix {
107 #[must_use]
109 pub fn new_static(description: &'static str, replacements: Vec<Replacement>) -> Self {
110 Self {
111 description: Cow::Borrowed(description),
112 replacements,
113 }
114 }
115
116 #[must_use]
118 pub fn new_dynamic(description: String, replacements: Vec<Replacement>) -> Self {
119 Self {
120 description: Cow::Owned(description),
121 replacements,
122 }
123 }
124}
125
126#[derive(Debug, Clone)]
127pub struct Replacement {
128 pub span: Span,
129 pub new_text: Cow<'static, str>,
130}
131
132impl Replacement {
133 #[must_use]
135 pub const fn new_static(span: Span, new_text: &'static str) -> Self {
136 Self {
137 span,
138 new_text: Cow::Borrowed(new_text),
139 }
140 }
141
142 #[must_use]
144 pub fn new_dynamic(span: Span, new_text: String) -> Self {
145 Self {
146 span,
147 new_text: Cow::Owned(new_text),
148 }
149 }
150}