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