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 Info,
9 Warning,
10 Error,
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)]
25pub(crate) struct RuleViolation {
26 pub rule_id: Cow<'static, str>,
27 pub message: Cow<'static, str>,
28 pub span: Span,
29 pub suggestion: Option<Cow<'static, str>>,
30 pub(crate) fix: Option<Fix>,
31}
32
33impl RuleViolation {
34 #[must_use]
36 pub(crate) const fn new_static(
37 rule_id: &'static str,
38 message: &'static str,
39 span: Span,
40 ) -> Self {
41 Self {
42 rule_id: Cow::Borrowed(rule_id),
43 message: Cow::Borrowed(message),
44 span,
45 suggestion: None,
46 fix: None,
47 }
48 }
49
50 #[must_use]
52 pub(crate) fn new_dynamic(rule_id: &'static str, message: String, span: Span) -> Self {
53 Self {
54 rule_id: Cow::Borrowed(rule_id),
55 message: Cow::Owned(message),
56 span,
57 suggestion: None,
58 fix: None,
59 }
60 }
61
62 #[must_use]
64 pub(crate) fn with_suggestion_static(mut self, suggestion: &'static str) -> Self {
65 self.suggestion = Some(Cow::Borrowed(suggestion));
66 self
67 }
68
69 #[must_use]
71 pub(crate) fn with_suggestion_dynamic(mut self, suggestion: String) -> Self {
72 self.suggestion = Some(Cow::Owned(suggestion));
73 self
74 }
75
76 #[must_use]
78 pub(crate) fn with_fix(mut self, fix: Fix) -> Self {
79 self.fix = Some(fix);
80 self
81 }
82
83 #[must_use]
85 pub fn into_violation(self, severity: Severity) -> Violation {
86 Violation {
87 rule_id: self.rule_id,
88 severity,
89 message: self.message,
90 span: self.span,
91 suggestion: self.suggestion,
92 fix: self.fix,
93 file: None,
94 }
95 }
96}
97
98#[derive(Debug, Clone)]
100pub struct Violation {
101 pub rule_id: Cow<'static, str>,
102 pub severity: Severity,
103 pub message: Cow<'static, str>,
104 pub span: Span,
105 pub suggestion: Option<Cow<'static, str>>,
106 pub(crate) fix: Option<Fix>,
107 pub file: Option<Cow<'static, str>>,
108}
109
110impl Violation {
111 #[must_use]
113 pub const fn new_static(
114 rule_id: &'static str,
115 severity: Severity,
116 message: &'static str,
117 span: Span,
118 ) -> Self {
119 Self {
120 rule_id: Cow::Borrowed(rule_id),
121 severity,
122 message: Cow::Borrowed(message),
123 span,
124 suggestion: None,
125 fix: None,
126 file: None,
127 }
128 }
129
130 #[must_use]
132 pub fn new_dynamic(
133 rule_id: &'static str,
134 severity: Severity,
135 message: String,
136 span: Span,
137 ) -> Self {
138 Self {
139 rule_id: Cow::Borrowed(rule_id),
140 severity,
141 message: Cow::Owned(message),
142 span,
143 suggestion: None,
144 fix: None,
145 file: None,
146 }
147 }
148
149 #[must_use]
151 pub fn with_suggestion_static(mut self, suggestion: &'static str) -> Self {
152 self.suggestion = Some(Cow::Borrowed(suggestion));
153 self
154 }
155
156 #[must_use]
158 pub fn with_suggestion_dynamic(mut self, suggestion: String) -> Self {
159 self.suggestion = Some(Cow::Owned(suggestion));
160 self
161 }
162
163 #[must_use]
165 pub(crate) fn to_source_span(&self) -> SourceSpan {
166 SourceSpan::from((self.span.start, self.span.end - self.span.start))
167 }
168}
169
170#[derive(Debug, Clone)]
171pub(crate) struct Fix {
172 pub(crate) description: Cow<'static, str>,
173 pub(crate) replacements: Vec<Replacement>,
174}
175
176impl Fix {
177 #[must_use]
179 pub fn new_static(description: &'static str, replacements: Vec<Replacement>) -> Self {
180 Self {
181 description: Cow::Borrowed(description),
182 replacements,
183 }
184 }
185
186 #[must_use]
188 pub(crate) fn new_dynamic(description: String, replacements: Vec<Replacement>) -> Self {
189 Self {
190 description: Cow::Owned(description),
191 replacements,
192 }
193 }
194}
195
196#[derive(Debug, Clone)]
197pub(crate) struct Replacement {
198 pub(crate) span: Span,
199 pub(crate) new_text: Cow<'static, str>,
200}
201
202impl Replacement {
203 #[must_use]
205 pub const fn new_static(span: Span, new_text: &'static str) -> Self {
206 Self {
207 span,
208 new_text: Cow::Borrowed(new_text),
209 }
210 }
211
212 #[must_use]
214 pub fn new_dynamic(span: Span, new_text: String) -> Self {
215 Self {
216 span,
217 new_text: Cow::Owned(new_text),
218 }
219 }
220}