1pub type Result<T, E = Error> = std::result::Result<T, E>;
5
6#[derive(Debug)]
7pub enum Error {
8 Io(std::io::Error),
9 NotFound(String),
10 Library(libloading::Error),
11 JpegEncoding(jpeg_encoder::EncodingError),
12 JpegDecoding(zune_jpeg::errors::DecodeErrors),
13 PngDecoding(zune_png::error::PngDecodeErrors),
14 ResizeImageBuffer(fast_image_resize::ImageBufferError),
15 Resize(fast_image_resize::ResizeError),
16 Yuv(yuv::YuvError),
17 #[cfg(target_os = "linux")]
18 G2D(g2d_sys::Error),
19 Tensor(edgefirst_tensor::Error),
20 NotImplemented(String),
21 NotSupported(String),
22 InvalidShape(String),
23 AliasedBuffers(String),
26 #[cfg(target_os = "linux")]
27 #[cfg(feature = "opengl")]
28 EGL(khronos_egl::Error),
29 GLVersion(String),
30 #[cfg(target_os = "linux")]
31 #[cfg(feature = "opengl")]
32 EGLLoad(khronos_egl::LoadError<libloading::Error>),
33 #[cfg(target_os = "linux")]
34 #[cfg(feature = "opengl")]
35 GbmInvalidFd(gbm::InvalidFdError),
36 #[cfg(target_os = "linux")]
37 #[cfg(feature = "opengl")]
38 GbmFrontBuffer(gbm::FrontBufferError),
39 OpenGl(String),
40 Internal(String),
41 CropInvalid(String),
42 ForcedBackendUnavailable(String),
43 NoConverter,
44 NotAnImage,
45 UnsupportedFormat(String),
46}
47
48impl From<std::io::Error> for Error {
49 fn from(err: std::io::Error) -> Self {
50 Error::Io(err)
51 }
52}
53
54impl From<libloading::Error> for Error {
55 fn from(err: libloading::Error) -> Self {
56 Error::Library(err)
57 }
58}
59
60impl From<jpeg_encoder::EncodingError> for Error {
61 fn from(err: jpeg_encoder::EncodingError) -> Self {
62 Error::JpegEncoding(err)
63 }
64}
65
66impl From<zune_jpeg::errors::DecodeErrors> for Error {
67 fn from(err: zune_jpeg::errors::DecodeErrors) -> Self {
68 Error::JpegDecoding(err)
69 }
70}
71
72impl From<zune_png::error::PngDecodeErrors> for Error {
73 fn from(err: zune_png::error::PngDecodeErrors) -> Self {
74 Error::PngDecoding(err)
75 }
76}
77
78impl From<fast_image_resize::ImageBufferError> for Error {
79 fn from(err: fast_image_resize::ImageBufferError) -> Self {
80 Error::ResizeImageBuffer(err)
81 }
82}
83
84impl From<fast_image_resize::ResizeError> for Error {
85 fn from(err: fast_image_resize::ResizeError) -> Self {
86 Error::Resize(err)
87 }
88}
89
90impl From<yuv::YuvError> for Error {
91 fn from(err: yuv::YuvError) -> Self {
92 Error::Yuv(err)
93 }
94}
95
96#[cfg(target_os = "linux")]
97impl From<g2d_sys::Error> for Error {
98 fn from(err: g2d_sys::Error) -> Self {
99 Error::G2D(err)
100 }
101}
102
103impl From<edgefirst_tensor::Error> for Error {
104 fn from(err: edgefirst_tensor::Error) -> Self {
105 Error::Tensor(err)
106 }
107}
108
109#[cfg(target_os = "linux")]
110#[cfg(feature = "opengl")]
111impl From<khronos_egl::Error> for Error {
112 fn from(err: khronos_egl::Error) -> Self {
113 Error::EGL(err)
114 }
115}
116
117#[cfg(target_os = "linux")]
118#[cfg(feature = "opengl")]
119impl From<khronos_egl::LoadError<libloading::Error>> for Error {
120 fn from(err: khronos_egl::LoadError<libloading::Error>) -> Self {
121 Error::EGLLoad(err)
122 }
123}
124
125#[cfg(target_os = "linux")]
126#[cfg(feature = "opengl")]
127impl From<gbm::InvalidFdError> for Error {
128 fn from(err: gbm::InvalidFdError) -> Self {
129 Error::GbmInvalidFd(err)
130 }
131}
132
133#[cfg(target_os = "linux")]
134#[cfg(feature = "opengl")]
135impl From<gbm::FrontBufferError> for Error {
136 fn from(err: gbm::FrontBufferError) -> Self {
137 Error::GbmFrontBuffer(err)
138 }
139}
140
141#[cfg(target_os = "linux")]
142#[cfg(feature = "opengl")]
143impl From<gls::Error> for Error {
144 fn from(err: gls::Error) -> Self {
145 Error::OpenGl(err.to_string())
146 }
147}
148
149impl From<ndarray::ShapeError> for Error {
150 fn from(err: ndarray::ShapeError) -> Self {
151 Error::Internal(format!("{err}"))
152 }
153}
154
155impl From<fast_image_resize::CropBoxError> for Error {
156 fn from(err: fast_image_resize::CropBoxError) -> Self {
157 Error::Internal(format!("{err}"))
158 }
159}
160
161impl std::fmt::Display for Error {
162 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163 write!(f, "{self:?}")
164 }
165}
166
167impl std::error::Error for Error {}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_image_error_display() {
175 let e = Error::Io(std::io::Error::new(
176 std::io::ErrorKind::NotFound,
177 "file missing",
178 ));
179 let msg = e.to_string();
180 assert!(!msg.is_empty());
181 assert!(
182 msg.contains("Io") && msg.contains("file missing"),
183 "unexpected Io message: {msg}"
184 );
185
186 let e = Error::NotFound("texture.png".to_string());
187 let msg = e.to_string();
188 assert!(!msg.is_empty());
189 assert!(
190 msg.contains("NotFound") && msg.contains("texture.png"),
191 "unexpected NotFound message: {msg}"
192 );
193
194 let e = Error::Tensor(edgefirst_tensor::Error::InvalidSize(42));
195 let msg = e.to_string();
196 assert!(!msg.is_empty());
197 assert!(
198 msg.contains("Tensor") && msg.contains("InvalidSize"),
199 "unexpected Tensor message: {msg}"
200 );
201
202 let e = Error::NotImplemented("webp".to_string());
203 let msg = e.to_string();
204 assert!(!msg.is_empty());
205 assert!(
206 msg.contains("NotImplemented") && msg.contains("webp"),
207 "unexpected NotImplemented message: {msg}"
208 );
209
210 let e = Error::NotSupported("bmp format".to_string());
211 let msg = e.to_string();
212 assert!(!msg.is_empty());
213 assert!(
214 msg.contains("NotSupported") && msg.contains("bmp format"),
215 "unexpected NotSupported message: {msg}"
216 );
217
218 let e = Error::InvalidShape("wrong dims".to_string());
219 let msg = e.to_string();
220 assert!(!msg.is_empty());
221 assert!(
222 msg.contains("InvalidShape") && msg.contains("wrong dims"),
223 "unexpected InvalidShape message: {msg}"
224 );
225
226 let e = Error::GLVersion("4.5 required".to_string());
227 let msg = e.to_string();
228 assert!(!msg.is_empty());
229 assert!(
230 msg.contains("GLVersion") && msg.contains("4.5 required"),
231 "unexpected GLVersion message: {msg}"
232 );
233
234 let e = Error::OpenGl("shader compile failed".to_string());
235 let msg = e.to_string();
236 assert!(!msg.is_empty());
237 assert!(
238 msg.contains("OpenGl") && msg.contains("shader compile failed"),
239 "unexpected OpenGl message: {msg}"
240 );
241
242 let e = Error::Internal("unexpected state".to_string());
243 let msg = e.to_string();
244 assert!(!msg.is_empty());
245 assert!(
246 msg.contains("Internal") && msg.contains("unexpected state"),
247 "unexpected Internal message: {msg}"
248 );
249
250 let e = Error::CropInvalid("out of bounds".to_string());
251 let msg = e.to_string();
252 assert!(!msg.is_empty());
253 assert!(
254 msg.contains("CropInvalid") && msg.contains("out of bounds"),
255 "unexpected CropInvalid message: {msg}"
256 );
257
258 let e = Error::ForcedBackendUnavailable("g2d".to_string());
259 let msg = e.to_string();
260 assert!(!msg.is_empty());
261 assert!(
262 msg.contains("ForcedBackendUnavailable") && msg.contains("g2d"),
263 "unexpected ForcedBackendUnavailable message: {msg}"
264 );
265
266 let e = Error::NoConverter;
267 let msg = e.to_string();
268 assert!(!msg.is_empty());
269 assert!(
270 msg.contains("NoConverter"),
271 "unexpected NoConverter message: {msg}"
272 );
273
274 let e = Error::NotAnImage;
275 let msg = e.to_string();
276 assert!(!msg.is_empty());
277 assert!(
278 msg.contains("NotAnImage"),
279 "unexpected NotAnImage message: {msg}"
280 );
281
282 let e = Error::UnsupportedFormat("tiff".to_string());
283 let msg = e.to_string();
284 assert!(!msg.is_empty());
285 assert!(
286 msg.contains("UnsupportedFormat") && msg.contains("tiff"),
287 "unexpected UnsupportedFormat message: {msg}"
288 );
289 }
290}