use crate::diagnostic_level::DiagnosticLevel;
use crate::file_path::FilePath;
use crate::shared_string::SharedString;
use crate::source_excerpt::SourceExcerpt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SourceDiagnostic {
pub level: DiagnosticLevel,
pub file_path: FilePath,
pub message: SharedString,
pub excerpts: Vec<SourceExcerpt>,
}
impl SourceDiagnostic {
pub fn new(
level: DiagnosticLevel,
file_path: impl Into<FilePath>,
message: impl Into<SharedString>,
) -> Self {
Self {
level,
file_path: file_path.into(),
message: message.into(),
excerpts: Vec::new(),
}
}
pub fn with_excerpt(mut self, excerpt: SourceExcerpt) -> Self {
self.excerpts.push(excerpt);
self
}
}
#[cfg(test)]
mod tests {
use super::SourceDiagnostic;
use crate::diagnostic_level::DiagnosticLevel;
use crate::source_annotation::SourceAnnotation;
use crate::source_excerpt::SourceExcerpt;
use crate::span::Span;
#[test]
fn source_diagnostic_tracks_level_file_and_excerpts() {
let diagnostic = SourceDiagnostic::new(
DiagnosticLevel::Error,
"examples/test.ocelot",
"unresolved identifier `value`",
)
.with_excerpt(
SourceExcerpt::new("examples/test.ocelot", 2, "println(value);")
.with_annotation(SourceAnnotation::new(Span::new(8, 13), "not found")),
);
assert_eq!(diagnostic.level, DiagnosticLevel::Error);
assert_eq!(diagnostic.file_path.as_str(), "examples/test.ocelot");
assert_eq!(diagnostic.message, "unresolved identifier `value`");
assert_eq!(diagnostic.excerpts.len(), 1);
assert_eq!(diagnostic.excerpts[0].line_number, 2);
assert_eq!(diagnostic.excerpts[0].annotations.len(), 1);
}
}