Skip to content

Commit 636d69e

Browse files
create diagnostic error trait
1 parent d38f08c commit 636d69e

File tree

3 files changed

+55
-80
lines changed

3 files changed

+55
-80
lines changed

crates/djls-ide/src/diagnostics.rs

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,55 @@ use djls_templates::TemplateErrorAccumulator;
66
use djls_workspace::SourceFile;
77
use tower_lsp_server::lsp_types;
88

9+
trait DiagnosticError: std::fmt::Display {
10+
fn span(&self) -> Option<(u32, u32)>;
11+
fn diagnostic_code(&self) -> &'static str;
12+
13+
fn message(&self) -> String {
14+
self.to_string()
15+
}
16+
}
17+
18+
impl DiagnosticError for TemplateError {
19+
fn span(&self) -> Option<(u32, u32)> {
20+
None
21+
}
22+
23+
fn diagnostic_code(&self) -> &'static str {
24+
match self {
25+
TemplateError::Parser(_) => "T100",
26+
TemplateError::Io(_) => "T900",
27+
TemplateError::Config(_) => "T901",
28+
}
29+
}
30+
}
31+
32+
impl DiagnosticError for ValidationError {
33+
fn span(&self) -> Option<(u32, u32)> {
34+
match self {
35+
ValidationError::UnbalancedStructure { opening_span, .. } => {
36+
Some((opening_span.start, opening_span.length))
37+
}
38+
ValidationError::UnclosedTag { span, .. }
39+
| ValidationError::OrphanedTag { span, .. }
40+
| ValidationError::UnmatchedBlockName { span, .. }
41+
| ValidationError::MissingRequiredArguments { span, .. }
42+
| ValidationError::TooManyArguments { span, .. } => Some((span.start, span.length)),
43+
}
44+
}
45+
46+
fn diagnostic_code(&self) -> &'static str {
47+
match self {
48+
ValidationError::UnclosedTag { .. } => "S100",
49+
ValidationError::UnbalancedStructure { .. } => "S101",
50+
ValidationError::OrphanedTag { .. } => "S102",
51+
ValidationError::UnmatchedBlockName { .. } => "S103",
52+
ValidationError::MissingRequiredArguments { .. } => "S104",
53+
ValidationError::TooManyArguments { .. } => "S105",
54+
}
55+
}
56+
}
57+
958
/// Convert a Span to an LSP Range using line offsets.
1059
fn span_to_lsp_range(span: Span, line_offsets: &LineOffsets) -> lsp_types::Range {
1160
let start_pos = span.start as usize;
@@ -26,37 +75,9 @@ fn span_to_lsp_range(span: Span, line_offsets: &LineOffsets) -> lsp_types::Range
2675
}
2776
}
2877

29-
/// Convert a template error to an LSP diagnostic.
30-
fn template_error_to_diagnostic(
31-
error: &TemplateError,
32-
line_offsets: &LineOffsets,
33-
) -> lsp_types::Diagnostic {
34-
let range = error
35-
.span()
36-
.map(|(start, length)| {
37-
let span = Span::new(start, length);
38-
span_to_lsp_range(span, line_offsets)
39-
})
40-
.unwrap_or_default();
41-
42-
lsp_types::Diagnostic {
43-
range,
44-
severity: Some(lsp_types::DiagnosticSeverity::ERROR),
45-
code: Some(lsp_types::NumberOrString::String(
46-
error.diagnostic_code().to_string(),
47-
)),
48-
code_description: None,
49-
source: Some("Django Language Server".to_string()),
50-
message: error.to_string(),
51-
related_information: None,
52-
tags: None,
53-
data: None,
54-
}
55-
}
56-
57-
/// Convert a validation error (`ValidationError`) to an LSP diagnostic.
58-
fn validation_error_to_diagnostic(
59-
error: &ValidationError,
78+
/// Convert any error implementing `DiagnosticError` to an LSP diagnostic.
79+
fn error_to_diagnostic(
80+
error: &impl DiagnosticError,
6081
line_offsets: &LineOffsets,
6182
) -> lsp_types::Diagnostic {
6283
let range = error
@@ -75,7 +96,7 @@ fn validation_error_to_diagnostic(
7596
)),
7697
code_description: None,
7798
source: Some("Django Language Server".to_string()),
78-
message: error.to_string(),
99+
message: error.message(),
79100
related_information: None,
80101
tags: None,
81102
data: None,
@@ -111,7 +132,7 @@ pub fn collect_diagnostics(
111132

112133
// Convert template errors to diagnostics
113134
for error_acc in template_errors {
114-
diagnostics.push(template_error_to_diagnostic(&error_acc.0, &line_offsets));
135+
diagnostics.push(error_to_diagnostic(&error_acc.0, &line_offsets));
115136
}
116137

117138
// If parsing succeeded, run validation
@@ -123,7 +144,7 @@ pub fn collect_diagnostics(
123144

124145
// Convert validation errors to diagnostics
125146
for error_acc in validation_errors {
126-
diagnostics.push(validation_error_to_diagnostic(&error_acc.0, &line_offsets));
147+
diagnostics.push(error_to_diagnostic(&error_acc.0, &line_offsets));
127148
}
128149
}
129150

crates/djls-semantic/src/errors.rs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,3 @@ pub enum ValidationError {
3232
#[error("Tag '{tag}' accepts at most {max} argument{}", if *.max == 1 { "" } else { "s" })]
3333
TooManyArguments { tag: String, max: usize, span: Span },
3434
}
35-
36-
impl ValidationError {
37-
/// Get the span start and length of this error, if available
38-
#[must_use]
39-
pub fn span(&self) -> Option<(u32, u32)> {
40-
match self {
41-
ValidationError::UnbalancedStructure { opening_span, .. } => {
42-
Some((opening_span.start, opening_span.length))
43-
}
44-
ValidationError::UnclosedTag { span, .. }
45-
| ValidationError::OrphanedTag { span, .. }
46-
| ValidationError::UnmatchedBlockName { span, .. }
47-
| ValidationError::MissingRequiredArguments { span, .. }
48-
| ValidationError::TooManyArguments { span, .. } => Some((span.start, span.length)),
49-
}
50-
}
51-
52-
/// Get a diagnostic code string for this error type
53-
#[must_use]
54-
pub fn diagnostic_code(&self) -> &'static str {
55-
match self {
56-
ValidationError::UnclosedTag { .. } => "S100",
57-
ValidationError::UnbalancedStructure { .. } => "S101",
58-
ValidationError::OrphanedTag { .. } => "S102",
59-
ValidationError::UnmatchedBlockName { .. } => "S103",
60-
ValidationError::MissingRequiredArguments { .. } => "S104",
61-
ValidationError::TooManyArguments { .. } => "S105",
62-
}
63-
}
64-
}

crates/djls-templates/src/error.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,3 @@ impl From<std::io::Error> for TemplateError {
2626
Self::Io(err.to_string())
2727
}
2828
}
29-
30-
impl TemplateError {
31-
#[must_use]
32-
pub fn span(&self) -> Option<(u32, u32)> {
33-
None
34-
}
35-
36-
#[must_use]
37-
pub fn diagnostic_code(&self) -> &'static str {
38-
match self {
39-
TemplateError::Parser(_) => "T100",
40-
TemplateError::Io(_) => "T900",
41-
TemplateError::Config(_) => "T901",
42-
}
43-
}
44-
}

0 commit comments

Comments
 (0)