Skip to main content

kozan_platform/renderer/
error.rs

1//! Renderer errors — unified error type for all renderer backends.
2
3use std::fmt;
4
5/// Error returned by renderer operations.
6///
7/// Backend-independent: both `kozan-vello` and any future backends
8/// map their internal errors into this type.
9#[derive(Debug)]
10pub enum RendererError {
11    /// Failed to acquire the GPU adapter.
12    AdapterNotFound,
13
14    /// Failed to create the GPU device.
15    DeviceCreation(String),
16
17    /// Failed to create the window surface.
18    SurfaceCreation(String),
19
20    /// The surface is not compatible with the adapter.
21    SurfaceIncompatible,
22
23    /// Failed to acquire the next surface texture.
24    SurfaceTextureAcquire(String),
25
26    /// The renderer backend produced an error during rendering.
27    RenderFailed(String),
28
29    /// The surface was lost (e.g., window minimized or resized race).
30    /// Caller should recreate the surface.
31    SurfaceLost,
32}
33
34impl fmt::Display for RendererError {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match self {
37            Self::AdapterNotFound => write!(f, "no suitable GPU adapter found"),
38            Self::DeviceCreation(e) => write!(f, "GPU device creation failed: {e}"),
39            Self::SurfaceCreation(e) => write!(f, "surface creation failed: {e}"),
40            Self::SurfaceIncompatible => {
41                write!(f, "surface is not compatible with the GPU adapter")
42            }
43            Self::SurfaceTextureAcquire(e) => write!(f, "failed to acquire surface texture: {e}"),
44            Self::RenderFailed(e) => write!(f, "render failed: {e}"),
45            Self::SurfaceLost => write!(f, "surface lost — recreate required"),
46        }
47    }
48}
49
50impl std::error::Error for RendererError {}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn display_adapter_not_found() {
58        let err = RendererError::AdapterNotFound;
59        assert_eq!(err.to_string(), "no suitable GPU adapter found");
60    }
61
62    #[test]
63    fn display_device_creation_includes_inner_message() {
64        let err = RendererError::DeviceCreation("out of memory".into());
65        assert_eq!(err.to_string(), "GPU device creation failed: out of memory");
66    }
67
68    #[test]
69    fn display_surface_creation_includes_inner_message() {
70        let err = RendererError::SurfaceCreation("unsupported format".into());
71        assert_eq!(
72            err.to_string(),
73            "surface creation failed: unsupported format"
74        );
75    }
76
77    #[test]
78    fn display_surface_incompatible() {
79        let err = RendererError::SurfaceIncompatible;
80        assert_eq!(
81            err.to_string(),
82            "surface is not compatible with the GPU adapter"
83        );
84    }
85
86    #[test]
87    fn display_surface_texture_acquire_includes_inner_message() {
88        let err = RendererError::SurfaceTextureAcquire("timeout".into());
89        assert_eq!(
90            err.to_string(),
91            "failed to acquire surface texture: timeout"
92        );
93    }
94
95    #[test]
96    fn display_render_failed_includes_inner_message() {
97        let err = RendererError::RenderFailed("shader compilation".into());
98        assert_eq!(err.to_string(), "render failed: shader compilation");
99    }
100
101    #[test]
102    fn display_surface_lost() {
103        let err = RendererError::SurfaceLost;
104        assert_eq!(err.to_string(), "surface lost — recreate required");
105    }
106
107    #[test]
108    fn debug_includes_variant_name() {
109        let err = RendererError::AdapterNotFound;
110        let debug = format!("{err:?}");
111        assert!(debug.contains("AdapterNotFound"));
112    }
113
114    #[test]
115    fn implements_std_error() {
116        let err = RendererError::RenderFailed("test".into());
117        let std_err: &dyn std::error::Error = &err;
118        assert!(std_err.source().is_none());
119    }
120}