1use std::{error::Error, fmt};
2
3#[derive(Clone, Debug)]
4pub struct ShaderError<E> {
5 pub source: String,
7 pub label: Option<String>,
8 pub inner: Box<E>,
9}
10
11#[cfg(feature = "wgsl-in")]
12impl fmt::Display for ShaderError<crate::front::wgsl::ParseError> {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 let label = self.label.as_deref().unwrap_or_default();
15 let string = self.inner.emit_to_string(&self.source);
16 write!(f, "\nShader '{label}' parsing {string}")
17 }
18}
19#[cfg(feature = "glsl-in")]
20impl fmt::Display for ShaderError<crate::front::glsl::ParseErrors> {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 let label = self.label.as_deref().unwrap_or_default();
23 let string = self.inner.emit_to_string(&self.source);
24 write!(f, "\nShader '{label}' parsing {string}")
25 }
26}
27#[cfg(feature = "spv-in")]
28impl fmt::Display for ShaderError<crate::front::spv::Error> {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 let label = self.label.as_deref().unwrap_or_default();
31 let string = self.inner.emit_to_string(&self.source);
32 write!(f, "\nShader '{label}' parsing {string}")
33 }
34}
35impl fmt::Display for ShaderError<crate::WithSpan<crate::valid::ValidationError>> {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 use codespan_reporting::{files::SimpleFile, term};
38
39 let label = self.label.as_deref().unwrap_or_default();
40 let files = SimpleFile::new(label, &self.source);
41 let config = term::Config::default();
42 let mut writer = termcolor::NoColor::new(Vec::new());
43 term::emit(&mut writer, &config, &files, &self.inner.diagnostic())
44 .expect("cannot write error");
45 write!(
46 f,
47 "\nShader validation {}",
48 String::from_utf8_lossy(&writer.into_inner())
49 )
50 }
51}
52impl<E> Error for ShaderError<E>
53where
54 ShaderError<E>: fmt::Display,
55 E: Error + 'static,
56{
57 fn source(&self) -> Option<&(dyn Error + 'static)> {
58 Some(&self.inner)
59 }
60}