kodept_macros/
traits.rs

1use std::convert::Infallible;
2use codespan_reporting::files::{Error, Files};
3use codespan_reporting::term::termcolor::WriteColor;
4use derive_more::{From, Unwrap};
5
6use kodept_ast::graph::SyntaxTree;
7use kodept_ast::traits::{Accessor, Linker};
8use kodept_core::code_point::CodePoint;
9use kodept_core::file_relative::CodePath;
10
11use crate::error::report::{Report, ReportMessage};
12use crate::error::traits::{CodespanSettings, Reportable};
13
14#[derive(Debug, From, Unwrap)]
15pub enum UnrecoverableError {
16    Report(Report),
17    Infallible(Infallible),
18}
19
20impl UnrecoverableError {
21    pub fn into_report(self) -> Report {
22        match self {
23            UnrecoverableError::Report(x) => x,
24            UnrecoverableError::Infallible(_) => unreachable!(),
25        }
26    }
27}
28
29impl Reportable for UnrecoverableError {
30    type FileId = ();
31
32    fn emit<'f, W: WriteColor, F: Files<'f, FileId=Self::FileId>>(self, settings: &mut CodespanSettings<W>, source: &'f F) -> Result<(), Error> {
33        self.into_report().emit(settings, source)
34    }
35}
36
37pub trait Reporter: FileContextual {
38    fn report_and_fail<R: Into<ReportMessage>, T>(
39        &self,
40        at: Vec<CodePoint>,
41        message: R,
42    ) -> Result<T, UnrecoverableError> {
43        Err(Report::new(&self.file_path(), at, message).into())
44    }
45
46    fn add_report<R: Into<ReportMessage>>(&mut self, at: Vec<CodePoint>, message: R) {
47        self.report(Report::new(&self.file_path(), at, message))
48    }
49
50    fn report(&mut self, report: Report);
51}
52
53pub trait FileContextual {
54    fn file_path(&self) -> CodePath;
55}
56
57pub trait Context: Linker + Accessor + Reporter {}
58
59pub trait MutableContext: Context {
60    fn modify_tree(
61        &mut self,
62        f: impl FnOnce(SyntaxTree) -> SyntaxTree,
63    ) -> Result<(), ReportMessage>;
64}
65
66impl<T: Linker + Accessor + Reporter> Context for T {}