microcad_lang/diag/
mod.rs1mod diag_handler;
14mod diag_list;
15mod diagnostic;
16mod level;
17
18pub use diag_handler::*;
19pub use diag_list::*;
20pub use diagnostic::*;
21pub use level::*;
22
23use crate::{eval::*, src_ref::*};
24
25pub trait PushDiag {
27 fn push_diag(&mut self, diag: Diagnostic) -> EvalResult<()>;
29
30 fn trace(&mut self, src: &impl SrcReferrer, message: String) {
32 self.push_diag(Diagnostic::Trace(Refer::new(message, src.src_ref())))
33 .expect("could not push diagnostic trace message");
34 }
35 fn info(&mut self, src: &impl SrcReferrer, message: String) {
37 self.push_diag(Diagnostic::Info(Refer::new(message, src.src_ref())))
38 .expect("could not push diagnostic info message");
39 }
40 fn warning(
42 &mut self,
43 src: &impl SrcReferrer,
44 error: impl std::error::Error + 'static,
45 ) -> EvalResult<()> {
46 self.push_diag(Diagnostic::Warning(Refer::new(error.into(), src.src_ref())))
47 }
48 fn error(
50 &mut self,
51 src: &impl SrcReferrer,
52 error: impl std::error::Error + 'static,
53 ) -> EvalResult<()> {
54 let err = Diagnostic::Error(Refer::new(error.into(), src.src_ref()));
55 log::error!("{err}");
56 self.push_diag(err)
57 }
58}
59
60pub trait Diag {
62 fn fmt_diagnosis(&self, f: &mut dyn std::fmt::Write) -> std::fmt::Result;
64
65 fn write_diagnosis(&self, w: &mut dyn std::io::Write) -> std::io::Result<()> {
67 write!(w, "{}", self.diagnosis())
68 }
69
70 fn diagnosis(&self) -> String {
72 let mut str = String::new();
73 self.fmt_diagnosis(&mut str).expect("displayable diagnosis");
74 str
75 }
76
77 fn has_errors(&self) -> bool {
79 self.error_count() > 0
80 }
81
82 fn error_count(&self) -> u32;
84
85 fn error_lines(&self) -> std::collections::HashSet<usize>;
87
88 fn warning_lines(&self) -> std::collections::HashSet<usize>;
90}
91
92pub trait WriteToFile: std::fmt::Display {
94 fn write_to_file(&self, filename: &impl AsRef<std::path::Path>) -> std::io::Result<()> {
96 use std::io::Write;
97 let file = std::fs::File::create(filename)?;
98 let mut writer = std::io::BufWriter::new(file);
99 write!(writer, "{self}")
100 }
101}