prism_parser/error/
set_error.rs1use crate::core::pos::Pos;
2use crate::core::span::Span;
3use crate::error::error_printer::{base_report, ErrorLabel};
4use crate::error::ParseError;
5use ariadne::{Label, Report};
6use std::cmp::max;
7use std::collections::{BTreeMap, HashSet};
8
9#[derive(Clone)]
11pub struct SetError<'grm> {
12 pub span: Span,
13 pub labels: HashSet<ErrorLabel<'grm>>,
14 pub explicit: bool,
15}
16
17impl<'grm> ParseError for SetError<'grm> {
18 type L = ErrorLabel<'grm>;
19
20 fn new(span: Span) -> Self {
21 Self {
22 span,
23 labels: HashSet::new(),
24 explicit: false,
25 }
26 }
27
28 fn add_label_explicit(&mut self, label: Self::L) {
29 if !self.explicit {
30 self.explicit = true;
31 self.labels.clear();
32 }
33 self.labels.insert(label);
34 }
35
36 fn add_label_implicit(&mut self, label: Self::L) {
37 if self.explicit {
38 return;
39 }
40 self.labels.insert(label);
41 }
42
43 fn merge(mut self, other: Self) -> Self {
44 assert_eq!(self.span.start, other.span.start);
45 for e in other.labels {
46 self.labels.insert(e);
47 }
48 Self {
49 span: Span::new(self.span.start, max(self.span.end, other.span.end)),
50 labels: self.labels,
51 explicit: self.explicit || other.explicit,
52 }
53 }
54
55 fn set_end(&mut self, end: Pos) {
56 self.span.end = end;
57 }
58
59 fn report(&self, enable_debug: bool) -> Report<'static, Span> {
60 let mut report = base_report(self.span);
61
62 let mut labels_map: BTreeMap<Pos, Vec<_>> = BTreeMap::new();
63 for l in self.labels.iter().filter(|l| enable_debug || !l.is_debug()) {
64 labels_map.entry(l.span().start).or_default().push(l);
65 }
66
67 for (start, labels) in labels_map {
69 report = report.with_label(
70 Label::new(start.span_to(start))
71 .with_message(format!(
72 "Tried parsing {}",
73 labels
74 .iter()
75 .map(|v| v.to_string())
76 .collect::<Vec<_>>()
77 .join(" / ")
78 ))
79 .with_order(-(<Pos as Into<usize>>::into(start) as i32)),
80 );
81 }
82
83 report.finish()
84 }
85}