ocelot_base/
source_diagnostic.rs1use crate::diagnostic_level::DiagnosticLevel;
2use crate::file_path::FilePath;
3use crate::shared_string::SharedString;
4use crate::source_excerpt::SourceExcerpt;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct SourceDiagnostic {
9 pub level: DiagnosticLevel,
11 pub file_path: FilePath,
13 pub message: SharedString,
15 pub excerpts: Vec<SourceExcerpt>,
17}
18
19impl SourceDiagnostic {
20 pub fn new(
22 level: DiagnosticLevel,
23 file_path: impl Into<FilePath>,
24 message: impl Into<SharedString>,
25 ) -> Self {
26 Self {
27 level,
28 file_path: file_path.into(),
29 message: message.into(),
30 excerpts: Vec::new(),
31 }
32 }
33
34 pub fn with_excerpt(mut self, excerpt: SourceExcerpt) -> Self {
36 self.excerpts.push(excerpt);
37 self
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::SourceDiagnostic;
44 use crate::diagnostic_level::DiagnosticLevel;
45 use crate::source_annotation::SourceAnnotation;
46 use crate::source_excerpt::SourceExcerpt;
47 use crate::span::Span;
48
49 #[test]
50 fn source_diagnostic_tracks_level_file_and_excerpts() {
51 let diagnostic = SourceDiagnostic::new(
52 DiagnosticLevel::Error,
53 "examples/test.ocelot",
54 "unresolved identifier `value`",
55 )
56 .with_excerpt(
57 SourceExcerpt::new("examples/test.ocelot", 2, "println(value);")
58 .with_annotation(SourceAnnotation::new(Span::new(8, 13), "not found")),
59 );
60
61 assert_eq!(diagnostic.level, DiagnosticLevel::Error);
62 assert_eq!(diagnostic.file_path.as_str(), "examples/test.ocelot");
63 assert_eq!(diagnostic.message, "unresolved identifier `value`");
64 assert_eq!(diagnostic.excerpts.len(), 1);
65 assert_eq!(diagnostic.excerpts[0].line_number, 2);
66 assert_eq!(diagnostic.excerpts[0].annotations.len(), 1);
67 }
68}