use ccutils::sync::{ArcRwLock, IntoArcRwLock};
use crate::prelude::*;
struct ReporterInner {
messages: Vec<Message>,
has_errors: bool,
}
#[derive(Clone)]
pub(crate) struct Reporter {
inner: ArcRwLock<ReporterInner>,
}
impl Reporter {
pub(crate) fn new() -> Reporter {
Reporter {
inner: ReporterInner {
messages: Default::default(),
has_errors: false,
}
.into_arc_rw_lock(),
}
}
pub(crate) fn handle_result<T, E>(
&self,
res: Result<T, E>,
severity: Severity,
msg: &'static str,
here: Here,
) -> Option<T>
where
E: std::fmt::Display,
{
match res {
Ok(t) => Some(t),
Err(e) => {
self.report_message(severity, format!("{}: '{}'", msg, e), here);
None
}
}
}
pub fn report_error(&self, msg: String, here: Here) {
self.report_message(Severity::Error, msg, here);
}
pub fn report_message(&self, severity: Severity, msg: String, here: Here) {
let mut inner = self.inner.write().unwrap();
inner.messages.push(Message {
severity,
content: msg,
filename: here.filename,
line: here.line,
});
match severity {
Severity::Error => inner.has_errors = true,
_ => {}
}
}
pub fn clone_messages(&self) -> Vec<Message> {
self.inner.read().unwrap().messages.clone()
}
pub fn for_each_message(&self, f: impl FnMut(&Message)) {
self.inner.read().unwrap().messages.iter().for_each(f);
}
pub fn messages_count(&self) -> usize {
self.inner.read().unwrap().messages.len()
}
pub fn has_errors(&self) -> bool {
self.inner.read().unwrap().has_errors
}
}