use crate::error::{Diagnostic, ParseError};
#[derive(Debug, Default)]
pub struct DiagnosticCollector {
diagnostics: Vec<Diagnostic>,
has_errors: bool,
}
impl DiagnosticCollector {
pub fn new() -> Self {
Self::default()
}
pub fn emit(&mut self, diagnostic: Diagnostic) {
if diagnostic.severity().is_error() {
self.has_errors = true;
}
self.diagnostics.push(diagnostic);
}
pub fn finish(self) -> Result<(), ParseError> {
if self.has_errors {
Err(ParseError::new(self.diagnostics))
} else {
Ok(())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{error::ErrorCode, span::Span};
#[test]
fn test_collector_new_finish_ok() {
let collector = DiagnosticCollector::new();
assert!(collector.finish().is_ok());
}
#[test]
fn test_collector_emit_error_finish_err() {
let mut collector = DiagnosticCollector::new();
collector.emit(Diagnostic::error("test error"));
assert!(collector.finish().is_err());
}
#[test]
fn test_collector_emit_warning_finish_ok() {
let mut collector = DiagnosticCollector::new();
collector.emit(Diagnostic::warning("test warning"));
assert!(collector.finish().is_ok());
}
#[test]
fn test_collector_emit_multiple_finish_err() {
let mut collector = DiagnosticCollector::new();
collector.emit(Diagnostic::error("error 1"));
collector.emit(Diagnostic::warning("warning 1"));
collector.emit(Diagnostic::error("error 2"));
assert!(collector.finish().is_err());
}
#[test]
fn test_collector_finish_with_errors() {
let mut collector = DiagnosticCollector::new();
collector.emit(
Diagnostic::error("test error")
.with_code(ErrorCode::E300)
.with_label(Span::new(10..20), "here"),
);
collector.emit(Diagnostic::warning("test warning"));
let result = collector.finish();
assert!(result.is_err());
let err = result.unwrap_err();
assert_eq!(err.diagnostics().len(), 2);
assert_eq!(err.diagnostics()[0].message(), "test error");
}
#[test]
fn test_collector_finish_warnings_only() {
let mut collector = DiagnosticCollector::new();
collector.emit(Diagnostic::warning("warning 1"));
collector.emit(Diagnostic::warning("warning 2"));
let result = collector.finish();
assert!(result.is_ok());
}
}