shader_sense/
shader_error.rs

1use core::fmt;
2use std::path::PathBuf;
3
4use crate::position::ShaderFileRange;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum ShaderDiagnosticSeverity {
8    Error,
9    Warning,
10    Information,
11    Hint,
12}
13impl fmt::Display for ShaderDiagnosticSeverity {
14    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15        match self {
16            ShaderDiagnosticSeverity::Error => write!(f, "error"),
17            ShaderDiagnosticSeverity::Warning => write!(f, "warning"),
18            ShaderDiagnosticSeverity::Information => write!(f, "info"),
19            ShaderDiagnosticSeverity::Hint => write!(f, "hint"),
20        }
21    }
22}
23
24impl From<&str> for ShaderDiagnosticSeverity {
25    fn from(value: &str) -> Self {
26        match value {
27            "error" => ShaderDiagnosticSeverity::Error,
28            "warning" => ShaderDiagnosticSeverity::Warning,
29            "info" => ShaderDiagnosticSeverity::Information,
30            "hint" => ShaderDiagnosticSeverity::Hint,
31            _ => ShaderDiagnosticSeverity::Error,
32        }
33    }
34}
35
36impl ShaderDiagnosticSeverity {
37    pub fn is_required(&self, required_severity: ShaderDiagnosticSeverity) -> bool {
38        self.get_enum_index() <= required_severity.get_enum_index()
39    }
40    fn get_enum_index(&self) -> u32 {
41        match self {
42            ShaderDiagnosticSeverity::Error => 0,
43            ShaderDiagnosticSeverity::Warning => 1,
44            ShaderDiagnosticSeverity::Information => 2,
45            ShaderDiagnosticSeverity::Hint => 3,
46        }
47    }
48}
49
50#[derive(Debug, Clone)]
51pub struct ShaderDiagnostic {
52    pub severity: ShaderDiagnosticSeverity,
53    pub error: String,
54    pub range: ShaderFileRange,
55}
56#[derive(Debug, Default, Clone)]
57pub struct ShaderDiagnosticList {
58    pub diagnostics: Vec<ShaderDiagnostic>,
59}
60
61#[derive(Debug)]
62pub enum ShaderError {
63    ValidationError(String),
64    NoSymbol,
65    ParseSymbolError(String),
66    SymbolQueryError(String, ShaderFileRange),
67    IoErr(std::io::Error),
68    InternalErr(String),
69    InvalidParams(String),
70    FileNotWatched(PathBuf),
71    SerializationError(serde_json::Error),
72}
73
74impl ShaderError {
75    pub fn into_diagnostic(&self, severity: ShaderDiagnosticSeverity) -> Option<ShaderDiagnostic> {
76        match self {
77            ShaderError::SymbolQueryError(message, range) => Some(ShaderDiagnostic {
78                error: format!(
79                    "Symbol Query {}, symbol provider may be impacted: {}",
80                    severity.to_string(),
81                    message
82                ),
83                severity: severity,
84                range: range.clone(),
85            }),
86            _ => None,
87        }
88    }
89}
90
91impl From<regex::Error> for ShaderError {
92    fn from(error: regex::Error) -> Self {
93        match error {
94            regex::Error::CompiledTooBig(err) => {
95                ShaderError::InternalErr(format!("Regex compile too big: {}", err))
96            }
97            regex::Error::Syntax(err) => {
98                ShaderError::InternalErr(format!("Regex syntax invalid: {}", err))
99            }
100            err => ShaderError::InternalErr(format!("Regex error: {:#?}", err)),
101        }
102    }
103}
104
105impl From<serde_json::Error> for ShaderError {
106    fn from(error: serde_json::Error) -> Self {
107        ShaderError::SerializationError(error)
108    }
109}
110
111impl fmt::Display for ShaderError {
112    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113        match self {
114            ShaderError::IoErr(err) => write!(f, "IoError: {}", err),
115            ShaderError::InternalErr(err) => write!(f, "Internal server error: {}", err),
116            ShaderError::NoSymbol => write!(f, "No symbol found"),
117            ShaderError::ParseSymbolError(err) => write!(f, "Failed to parse symbols: {}", err),
118            ShaderError::ValidationError(err) => write!(f, "Validation error: {}", err),
119            ShaderError::SerializationError(err) => write!(f, "Error with serialization: {}", err),
120            ShaderError::FileNotWatched(uri) => write!(f, "File not watched: {}", uri.display()),
121            ShaderError::InvalidParams(err) => write!(f, "Invalid params: {}", err),
122            ShaderError::SymbolQueryError(err, range) => {
123                write!(f, "SymbolQueryError: {} at {:?}", err, range)
124            }
125        }
126    }
127}
128
129impl From<std::io::Error> for ShaderError {
130    fn from(err: std::io::Error) -> Self {
131        ShaderError::IoErr(err)
132    }
133}
134impl From<ShaderDiagnostic> for ShaderDiagnosticList {
135    fn from(err: ShaderDiagnostic) -> Self {
136        Self {
137            diagnostics: vec![err],
138        }
139    }
140}
141impl ShaderDiagnosticList {
142    pub fn empty() -> Self {
143        Self {
144            diagnostics: Vec::new(),
145        }
146    }
147    pub fn push(&mut self, error: ShaderDiagnostic) {
148        self.diagnostics.push(error);
149    }
150    pub fn is_empty(&self) -> bool {
151        self.diagnostics.is_empty()
152    }
153    pub fn join(mut lhs: ShaderDiagnosticList, rhs: ShaderDiagnosticList) -> Self {
154        lhs.diagnostics.extend(rhs.diagnostics);
155        lhs
156    }
157}