kcl_error/
lib.rs

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