microcad_lang/diag/
mod.rs1mod diag_error;
14mod diag_handler;
15mod diag_list;
16mod diagnostic;
17mod level;
18
19use miette::Report;
20pub use diag_error::*;
21pub use diag_handler::*;
22pub use diag_list::*;
23pub use diagnostic::*;
24pub use level::*;
25
26use crate::src_ref::*;
27
28pub trait PushDiag {
30 fn push_diag(&mut self, diag: Diagnostic) -> DiagResult<()>;
32
33 fn trace(&mut self, src: &impl SrcReferrer, message: String) {
35 self.push_diag(Diagnostic::Trace(Refer::new(Report::msg(message), src.src_ref())))
36 .expect("could not push diagnostic trace message");
37 }
38 fn info(&mut self, src: &impl SrcReferrer, message: String) {
40 self.push_diag(Diagnostic::Info(Refer::new(Report::msg(message), src.src_ref())))
41 .expect("could not push diagnostic info message");
42 }
43 fn warning(
45 &mut self,
46 src: &impl SrcReferrer,
47 err: impl Into<Report>,
48 ) -> DiagResult<()> {
49 let err = Diagnostic::Warning(Refer::new(err.into(), src.src_ref()));
50 if cfg!(feature = "ansi-color") {
51 log::warn!("{}", color_print::cformat!("<y,s>{err}</>"));
52 } else {
53 log::warn!("{err}");
54 }
55 self.push_diag(err)
56 }
57 fn error(
59 &mut self,
60 src: &impl SrcReferrer,
61 err: impl Into<Report>,
62 ) -> DiagResult<()> {
63 let err = Diagnostic::Error(Refer::new(err.into(), src.src_ref()));
64 if cfg!(feature = "ansi-color") {
65 log::error!("{}", color_print::cformat!("<r,s>{err}</>"));
66 } else {
67 log::error!("{err}");
68 }
69 self.push_diag(err)
70 }
71}
72
73pub trait Diag {
75 fn fmt_diagnosis(&self, f: &mut dyn std::fmt::Write) -> std::fmt::Result;
77
78 fn write_diagnosis(&self, w: &mut dyn std::io::Write) -> std::io::Result<()> {
80 write!(w, "{}", self.diagnosis())
81 }
82
83 fn diagnosis(&self) -> String {
85 let mut str = String::new();
86 self.fmt_diagnosis(&mut str).expect("displayable diagnosis");
87 str
88 }
89
90 fn has_warnings(&self) -> bool {
92 self.warning_count() > 0
93 }
94
95 fn warning_count(&self) -> u32;
97
98 fn has_errors(&self) -> bool {
100 self.error_count() > 0
101 }
102
103 fn error_count(&self) -> u32;
105
106 fn error_lines(&self) -> std::collections::HashSet<usize>;
108
109 fn warning_lines(&self) -> std::collections::HashSet<usize>;
111}
112
113pub trait WriteToFile: std::fmt::Display {
115 fn write_to_file(&self, filename: &impl AsRef<std::path::Path>) -> std::io::Result<()> {
117 use std::io::Write;
118 let file = std::fs::File::create(filename)?;
119 let mut writer = std::io::BufWriter::new(file);
120 write!(writer, "{self}")
121 }
122}