1use ariadne::{Config, Label, Report, ReportKind, Source};
2use serde::{Deserialize, Serialize};
3
4use crate::{SourceId, Span};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ErrorReport {
8 pub span: Span,
9 pub message: String,
10 pub labels: Vec<(Span, String)>,
11 pub notes: Vec<String>,
12}
13
14impl ErrorReport {
15 pub fn display(&self, source: &str, source_id: SourceId) {
16 let mut report = Report::build(ReportKind::Error, self.span.source(), self.span.end())
17 .with_message(self.message.clone());
18
19 for (i, (span, msg)) in self.labels.clone().into_iter().enumerate() {
20 report = report.with_label(Label::new(span).with_message(msg).with_order(i as i32));
21 }
22
23 for note in &self.notes {
24 report = report.with_note(note);
25 }
26
27 report
28 .with_config(Config::default().with_compact(false))
29 .finish()
30 .eprint((source_id.clone(), Source::from(source)))
31 .unwrap();
32 }
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct ErrorReports {
37 pub reports: Vec<ErrorReport>,
38}
39
40impl From<Vec<ErrorReport>> for ErrorReports {
41 fn from(reports: Vec<ErrorReport>) -> Self {
42 ErrorReports { reports }
43 }
44}