par_term_render/error.rs
1//! Typed error types for par-term-render.
2//!
3//! This module provides structured error types so callers at the crate boundary
4//! can match on specific error variants instead of relying on opaque `anyhow`
5//! strings.
6
7use thiserror::Error;
8
9/// Top-level error type for the GPU rendering engine.
10///
11/// Covers the main failure categories that callers may want to distinguish:
12/// - GPU initialisation (adapter, device, surface)
13/// - Shader compilation and reload
14/// - Image / texture loading
15/// - GPU surface / presentation
16/// - Screenshot capture
17#[derive(Debug, Error)]
18pub enum RenderError {
19 // -----------------------------------------------------------------------
20 // GPU initialisation
21 // -----------------------------------------------------------------------
22 /// A suitable wgpu GPU adapter could not be found for the given surface.
23 #[error("GPU adapter not found: no compatible GPU adapter available for this surface")]
24 AdapterNotFound,
25
26 /// The wgpu device could not be created or the device was lost.
27 #[error("GPU device error: {0}")]
28 DeviceError(String),
29
30 /// The wgpu surface could not be created for the window.
31 #[error("GPU surface creation failed: {0}")]
32 SurfaceCreation(String),
33
34 // -----------------------------------------------------------------------
35 // Shader errors
36 // -----------------------------------------------------------------------
37 /// The shader source file could not be read from disk.
38 #[error("Shader file read failed for '{path}': {source}")]
39 ShaderFileRead {
40 /// Path to the shader file that could not be read.
41 path: String,
42 /// Underlying I/O error.
43 #[source]
44 source: std::io::Error,
45 },
46
47 /// The GLSL source could not be parsed (transpilation step 1).
48 #[error("GLSL parse error in '{name}':\n{details}")]
49 GlslParse {
50 /// Shader name or path.
51 name: String,
52 /// Human-readable parse error messages.
53 details: String,
54 },
55
56 /// The intermediate WGSL source could not be parsed.
57 #[error("WGSL parse error for '{name}': {details}")]
58 WgslParse {
59 /// Shader name or path.
60 name: String,
61 /// Human-readable parse error details.
62 details: String,
63 },
64
65 /// The shader module failed naga validation.
66 #[error("Shader validation failed for '{name}': {details}")]
67 ShaderValidation {
68 /// Shader name or path.
69 name: String,
70 /// Human-readable validation error details.
71 details: String,
72 },
73
74 /// WGSL generation (from the naga IR) failed.
75 #[error("WGSL code generation failed for '{name}': {details}")]
76 WgslGeneration {
77 /// Shader name or path.
78 name: String,
79 /// Human-readable generation error details.
80 details: String,
81 },
82
83 /// A shader reload was requested but no shader is currently active,
84 /// or a shader compilation error occurred during reload.
85 #[error("Shader error: {0}")]
86 NoActiveShader(String),
87
88 // -----------------------------------------------------------------------
89 // Image / texture loading
90 // -----------------------------------------------------------------------
91 /// An image file could not be opened or decoded.
92 #[error("Image load failed for '{path}': {source}")]
93 ImageLoad {
94 /// Path to the image that failed to load.
95 path: String,
96 /// Underlying image error.
97 #[source]
98 source: image::ImageError,
99 },
100
101 /// The supplied raw RGBA byte slice has an unexpected length.
102 #[error("Invalid RGBA data size: expected {expected} bytes, got {actual} bytes")]
103 InvalidTextureData {
104 /// Expected byte count (`width * height * 4`).
105 expected: usize,
106 /// Actual byte count received.
107 actual: usize,
108 },
109
110 /// A cubemap face image is not square or all faces are not the same size.
111 #[error("Cubemap geometry error: {0}")]
112 CubemapGeometry(String),
113
114 /// A required cubemap face file could not be found on disk.
115 #[error("Cubemap face file not found: {0}")]
116 CubemapFaceNotFound(String),
117
118 // -----------------------------------------------------------------------
119 // Surface / presentation
120 // -----------------------------------------------------------------------
121 /// `Surface::get_current_texture()` failed (timeout, outdated, lost, ...).
122 #[error("GPU surface error: {0}")]
123 Surface(#[from] wgpu::SurfaceError),
124
125 // -----------------------------------------------------------------------
126 // Screenshot
127 // -----------------------------------------------------------------------
128 /// The GPU buffer could not be mapped back to CPU memory, or a render
129 /// step during screenshot capture failed.
130 #[error("Screenshot capture failed: {0}")]
131 ScreenshotMap(String),
132
133 /// The pixel data could not be assembled into a final `RgbaImage`.
134 #[error("Screenshot image assembly failed")]
135 ScreenshotImageAssembly,
136}
137
138// ---------------------------------------------------------------------------
139// Convenience conversions from common upstream error types
140// ---------------------------------------------------------------------------
141
142impl From<wgpu::CreateSurfaceError> for RenderError {
143 fn from(e: wgpu::CreateSurfaceError) -> Self {
144 RenderError::SurfaceCreation(e.to_string())
145 }
146}
147
148impl From<wgpu::RequestDeviceError> for RenderError {
149 fn from(e: wgpu::RequestDeviceError) -> Self {
150 RenderError::DeviceError(e.to_string())
151 }
152}