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
72#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, ts_rs::TS)]
73#[ts(export)]
74pub enum Severity {
75 Warning,
76 Error,
77 Fatal,
78}
79
80impl Severity {
81 pub fn is_err(self) -> bool {
82 match self {
83 Severity::Warning => false,
84 Severity::Error | Severity::Fatal => true,
85 }
86 }
87}
88
89#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, ts_rs::TS)]
90#[ts(export)]
91pub enum Tag {
92 Deprecated,
93 Unnecessary,
94 UnknownNumericUnits,
95 None,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, ts_rs::TS, PartialEq, Eq)]
99#[ts(export)]
100pub struct Suggestion {
101 pub title: String,
102 pub insert: String,
103 pub source_range: SourceRange,
104}
105
106impl Suggestion {
107 pub fn apply(&self, src: &str) -> String {
109 format!(
110 "{}{}{}",
111 &src[0..self.source_range.start()],
112 self.insert,
113 &src[self.source_range.end()..]
114 )
115 }
116}