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