Skip to main content

pactole_syntax/
diagnostics.rs

1//! Diagnostics reported while tolerantly parsing a `.pactole` source text.
2
3use crate::span::Span;
4
5/// The nature of a syntax diagnostic, mirroring tree-sitter's own error taxonomy.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum DiagnosticKind {
8    /// The parser encountered a sequence of tokens it could not fit into the grammar.
9    /// Corresponds to a tree-sitter `ERROR` node.
10    Error,
11    /// The parser inferred that a token was expected but absent from the input.
12    /// Corresponds to a tree-sitter "missing" node.
13    Missing,
14}
15
16/// A single syntax-level diagnostic produced by tolerant parsing.
17///
18/// Diagnostics are purely syntactic: they do not reference `pactole-core` domain
19/// concepts and only describe where the concrete syntax tree deviates from a
20/// fully valid parse.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct SyntaxDiagnostic {
23    /// Whether this diagnostic reports an `ERROR` node or a `MISSING` node.
24    pub kind: DiagnosticKind,
25    /// The span in the source text this diagnostic refers to.
26    pub span: Span,
27    /// A human-readable description of the diagnostic (e.g. "missing an
28    /// account name in an `open` directive", or "unexpected syntax after a
29    /// date: `foo bar`"), derived from the tree-sitter node's kind and its
30    /// surrounding context (parent node kind) rather than a raw
31    /// tree-sitter S-expression.
32    pub message: String,
33}
34
35impl SyntaxDiagnostic {
36    /// Builds a new [`SyntaxDiagnostic`].
37    pub fn new(kind: DiagnosticKind, span: Span, message: impl Into<String>) -> Self {
38        Self {
39            kind,
40            span,
41            message: message.into(),
42        }
43    }
44}