///|
/// The stage that produced a diagnostic.
pub(all) enum DiagnosticStage {
Lex
Parse
Evaluate
Configure
} derive(Eq, Debug, ToJson, FromJson)
///|
/// A stable, structured error intended for editors, CLIs, and CI reports.
pub(all) struct Diagnostic {
stage : DiagnosticStage
code : String
message : String
span : Span
hint : String?
} derive(Eq, Debug, ToJson, FromJson)
///|
pub fn Diagnostic::new(
stage : DiagnosticStage,
code : String,
message : String,
span : Span,
hint? : String,
) -> Diagnostic {
{ stage, code, message, span, hint }
}
///|
pub fn Diagnostic::render(self : Diagnostic, source : String) -> String {
let prefix = match self.stage {
Lex => "lex"
Parse => "parse"
Evaluate => "evaluate"
Configure => "configure"
}
let excerpt = if self.span.start >= 0 &&
self.span.end >= self.span.start &&
self.span.end <= source.length() {
source[self.span.start:self.span.end].to_owned()
} else {
""
}
let hint = match self.hint {
Some(value) => "\nhint: \{value}"
None => ""
}
"\{prefix}[\{self.code}] at \{self.span.start}..\{self.span.end}: \{self.message}\nsource: \{excerpt}\{hint}"
}
///|
priv suberror RuleFailure {
RuleFailure(Diagnostic)
}