orrery_parser/error/
parse_error.rs1use std::fmt;
8
9use crate::{error::Diagnostic, source_map::SourceMap};
10
11pub type Result<T> = std::result::Result<T, Diagnostic>;
13
14#[derive(Debug, thiserror::Error)]
18pub struct ParseError<'a> {
19 diagnostics: Vec<Diagnostic>,
20 source_map: SourceMap<'a>,
21}
22
23impl fmt::Display for ParseError<'_> {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 if let Some(first) = self.diagnostics.first() {
26 write!(f, "{}", first)?;
27 if self.diagnostics.len() > 1 {
28 write!(f, " (+{} more)", self.diagnostics.len() - 1)?;
29 }
30 }
31 Ok(())
32 }
33}
34
35impl<'a> ParseError<'a> {
36 pub fn new(diagnostics: Vec<Diagnostic>, source_map: SourceMap<'a>) -> Self {
38 Self {
39 diagnostics,
40 source_map,
41 }
42 }
43
44 pub fn from_diagnostic(diagnostic: Diagnostic, source_map: SourceMap<'a>) -> Self {
46 Self {
47 diagnostics: vec![diagnostic],
48 source_map,
49 }
50 }
51
52 pub fn source_map(&self) -> &SourceMap<'a> {
54 &self.source_map
55 }
56
57 pub fn diagnostics(&self) -> &[Diagnostic] {
59 &self.diagnostics
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use crate::error::ErrorCode;
67
68 #[test]
69 fn test_parse_error_new() {
70 let diag = Diagnostic::error("test error").with_code(ErrorCode::E300);
71 let err = ParseError::new(vec![diag], SourceMap::new());
72
73 assert_eq!(err.diagnostics().len(), 1);
74 assert_eq!(err.diagnostics()[0].message(), "test error");
75 }
76
77 #[test]
78 fn test_parse_error_new_multi_diagnostics() {
79 let diags = vec![Diagnostic::error("error 1"), Diagnostic::error("error 2")];
80 let err = ParseError::new(diags, SourceMap::new());
81
82 assert_eq!(err.diagnostics().len(), 2);
83 }
84
85 #[test]
86 fn test_parse_error_from_diagnostic() {
87 let diag = Diagnostic::error("test error").with_code(ErrorCode::E300);
88 let err = ParseError::from_diagnostic(diag, SourceMap::new());
89
90 assert_eq!(err.diagnostics().len(), 1);
91 assert_eq!(err.diagnostics()[0].message(), "test error");
92 }
93
94 #[test]
95 fn test_parse_error_source_map_accessor() {
96 let mut sm = SourceMap::new();
97 sm.add_file("test.orr", "hello", None);
98 let err = ParseError::new(vec![Diagnostic::error("err")], sm);
99
100 assert_eq!(err.source_map().file_count(), 1);
101 }
102
103 #[test]
104 fn test_parse_error_display_single() {
105 let diag = Diagnostic::error("undefined type");
106 let err = ParseError::from_diagnostic(diag, SourceMap::new());
107
108 assert_eq!(err.to_string(), "error: undefined type");
109 }
110
111 #[test]
112 fn test_parse_error_display_multiple() {
113 let diags = vec![
114 Diagnostic::error("first error"),
115 Diagnostic::error("second error"),
116 Diagnostic::error("third error"),
117 ];
118 let err = ParseError::new(diags, SourceMap::new());
119
120 assert_eq!(err.to_string(), "error: first error (+2 more)");
121 }
122}