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