prism_parser/error/
error_printer.rs1use crate::core::span::Span;
2use crate::grammar::escaped_string::EscapedString;
3use ariadne::{Color, Config, Label, LabelAttach, Report, ReportBuilder, ReportKind};
4use std::fmt::{Display, Formatter};
5
6#[derive(Eq, Hash, Clone, PartialEq)]
7pub enum ErrorLabel<'grm> {
8 Explicit(Span, EscapedString<'grm>),
9 Literal(Span, EscapedString<'grm>),
10 Debug(Span, &'grm str),
11}
12
13impl ErrorLabel<'_> {
14 pub(crate) fn span(&self) -> Span {
15 match self {
16 ErrorLabel::Explicit(s, _) => *s,
17 ErrorLabel::Literal(s, _) => *s,
18 ErrorLabel::Debug(s, _) => *s,
19 }
20 }
21
22 pub(crate) fn is_debug(&self) -> bool {
23 match self {
24 ErrorLabel::Explicit(_, _) => false,
25 ErrorLabel::Literal(_, _) => false,
26 ErrorLabel::Debug(_, _) => true,
27 }
28 }
29}
30
31impl Display for ErrorLabel<'_> {
32 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
33 match self {
34 ErrorLabel::Explicit(_, s) => write!(f, "{}", s),
35 ErrorLabel::Literal(_, s) => write!(f, "'{}'", s),
36 ErrorLabel::Debug(_, s) => write!(f, "[{}]", s),
37 }
38 }
39}
40
41pub fn base_report(span: Span) -> ReportBuilder<'static, Span> {
42 Report::build(ReportKind::Error, (), 0)
43 .with_config(Config::default().with_label_attach(LabelAttach::Start))
45 .with_message("Parsing error")
47 .with_label(
49 Label::new(span)
50 .with_message(match span.end - span.start {
51 0 => "Failed to parse at this location (but recovered immediately)",
52 1 => "This character was unparsable",
53 _ => "These characters were unparsable",
54 })
55 .with_color(Color::Red)
56 .with_priority(1)
57 .with_order(i32::MIN),
58 )
59}
60
61impl ariadne::Span for Span {
62 type SourceId = ();
63
64 fn source(&self) -> &Self::SourceId {
65 &()
66 }
67
68 fn start(&self) -> usize {
69 self.start.into()
70 }
71
72 fn end(&self) -> usize {
73 self.end.into()
74 }
75}