okane_core/report/
error.rs1use std::{fmt::Display, path::PathBuf};
4
5use annotate_snippets::{Annotation, Level, Snippet};
6
7use crate::{
8 load,
9 parse::{self, ParsedSpan},
10};
11
12use super::book_keeping::{self, BookKeepError};
13
14#[derive(thiserror::Error, Debug)]
16pub enum ReportError {
17 Load(#[from] load::LoadError),
18 BookKeep(book_keeping::BookKeepError, Box<ErrorContext>),
19}
20
21impl Display for ReportError {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 match self {
24 ReportError::Load(_) => write!(f, "failed to load the given file"),
25 ReportError::BookKeep(err, ctx) => ctx.print(f, err),
26 }
27 }
28}
29
30#[derive(Debug)]
32pub struct ErrorContext {
33 renderer: annotate_snippets::Renderer,
34 path: PathBuf,
35 line_start: usize,
36 text: String,
37 parsed_span: ParsedSpan,
38}
39
40impl ErrorContext {
41 fn print(&self, f: &mut std::fmt::Formatter<'_>, err: &BookKeepError) -> std::fmt::Result {
42 let message = err.to_string();
43 let path = self.path.to_string_lossy();
44 let annotations: Vec<Annotation> = match err {
45 BookKeepError::UndeduciblePostingAmount(first, second) => {
46 vec![
47 Level::Warning
48 .span(self.parsed_span.resolve(first.span()))
49 .label("first posting that requires deduce"),
50 Level::Error
51 .span(self.parsed_span.resolve(second.span()))
52 .label("either this or previous posting must specify the amount"),
53 ]
54 }
55 _ => {
56 vec![Level::Error.span(0..self.text.len()).label("error occured")]
59 }
60 };
61 let message = Level::Error.title(&message).snippet(
62 Snippet::source(&self.text)
63 .origin(&path)
64 .line_start(self.line_start)
65 .annotations(annotations),
66 );
67 let rendered = self.renderer.render(message);
68 rendered.fmt(f)
69 }
70
71 pub(super) fn new(
72 renderer: annotate_snippets::Renderer,
73 path: PathBuf,
74 pctx: &parse::ParsedContext,
75 ) -> Box<Self> {
76 Box::new(Self {
77 renderer,
78 path,
79 line_start: pctx.compute_line_start(),
80 text: pctx.as_str().to_owned(),
81 parsed_span: pctx.span(),
82 })
83 }
84}