1use serde::Deserialize;
2use serde::Serialize;
3pub use source_range::ModuleId;
4pub use source_range::SourceRange;
5
6mod source_range;
7
8#[derive(Debug, Clone, Serialize, Deserialize, ts_rs::TS, PartialEq, Eq)]
10#[ts(export)]
11pub struct CompilationError {
12 #[serde(rename = "sourceRange")]
13 pub source_range: SourceRange,
14 pub message: String,
15 pub suggestion: Option<Suggestion>,
16 pub severity: Severity,
17 pub tag: Tag,
18}
19
20impl CompilationError {
21 pub fn err(source_range: SourceRange, message: impl ToString) -> CompilationError {
22 CompilationError {
23 source_range,
24 message: message.to_string(),
25 suggestion: None,
26 severity: Severity::Error,
27 tag: Tag::None,
28 }
29 }
30
31 pub fn fatal(source_range: SourceRange, message: impl ToString) -> CompilationError {
32 CompilationError {
33 source_range,
34 message: message.to_string(),
35 suggestion: None,
36 severity: Severity::Fatal,
37 tag: Tag::None,
38 }
39 }
40
41 pub fn with_suggestion(
42 self,
43 suggestion_title: impl ToString,
44 suggestion_insert: impl ToString,
45 source_range: Option<SourceRange>,
47 tag: Tag,
48 ) -> CompilationError {
49 CompilationError {
50 suggestion: Some(Suggestion {
51 title: suggestion_title.to_string(),
52 insert: suggestion_insert.to_string(),
53 source_range: source_range.unwrap_or(self.source_range),
54 }),
55 tag,
56 ..self
57 }
58 }
59
60 #[cfg(test)]
61 pub fn apply_suggestion(&self, src: &str) -> Option<String> {
62 let suggestion = self.suggestion.as_ref()?;
63 Some(format!(
64 "{}{}{}",
65 &src[0..suggestion.source_range.start()],
66 suggestion.insert,
67 &src[suggestion.source_range.end()..]
68 ))
69 }
70
71 pub fn is_err(&self) -> bool {
72 self.severity.is_err()
73 }
74}
75
76#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, ts_rs::TS)]
77#[ts(export)]
78pub enum Severity {
79 Warning,
80 Error,
81 Fatal,
82}
83
84impl Severity {
85 pub fn is_err(self) -> bool {
86 match self {
87 Severity::Warning => false,
88 Severity::Error | Severity::Fatal => true,
89 }
90 }
91}
92
93#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, ts_rs::TS)]
94#[ts(export)]
95pub enum Tag {
96 Deprecated,
97 Unnecessary,
98 UnknownNumericUnits,
99 None,
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize, ts_rs::TS, PartialEq, Eq)]
103#[ts(export)]
104pub struct Suggestion {
105 pub title: String,
106 pub insert: String,
107 pub source_range: SourceRange,
108}
109
110impl Suggestion {
111 pub fn apply(&self, src: &str) -> String {
113 format!(
114 "{}{}{}",
115 &src[0..self.source_range.start()],
116 self.insert,
117 &src[self.source_range.end()..]
118 )
119 }
120}