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