Skip to main content

gdck_syntax/
error.rs

1//! Diagnostics produced while lexing and parsing.
2
3use std::fmt;
4
5use crate::text::{LineIndex, TextRange};
6
7/// A problem found while turning source text into a tree.
8///
9/// Errors never stop the lexer or parser — both always produce a complete,
10/// lossless tree. An error means part of that tree is wrapped in
11/// [`SyntaxKind::Error`](crate::SyntaxKind::Error), not that parsing gave up.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct SyntaxError {
14    range: TextRange,
15    message: String,
16}
17
18impl SyntaxError {
19    #[must_use]
20    pub fn new(range: TextRange, message: impl Into<String>) -> Self {
21        Self {
22            range,
23            message: message.into(),
24        }
25    }
26
27    #[must_use]
28    pub fn range(&self) -> TextRange {
29        self.range
30    }
31
32    #[must_use]
33    pub fn message(&self) -> &str {
34        &self.message
35    }
36
37    /// Render as `line:col: message`, the shape most editors and CI log
38    /// scrapers expect.
39    #[must_use]
40    pub fn display_with(&self, index: &LineIndex) -> String {
41        format!("{}: {}", index.line_col(self.range.start()), self.message)
42    }
43}
44
45impl fmt::Display for SyntaxError {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        write!(f, "{}: {}", self.range, self.message)
48    }
49}
50
51impl std::error::Error for SyntaxError {}