1 | use std::{error, fmt}; |
2 | |
3 | use crate::platform_impl; |
4 | |
5 | // TODO: Rename |
6 | /// An error that may be generated when requesting Winit state |
7 | #[derive (Debug)] |
8 | pub enum ExternalError { |
9 | /// The operation is not supported by the backend. |
10 | NotSupported(NotSupportedError), |
11 | /// The operation was ignored. |
12 | Ignored, |
13 | /// The OS cannot perform the operation. |
14 | Os(OsError), |
15 | } |
16 | |
17 | /// The error type for when the requested operation is not supported by the backend. |
18 | #[derive (Clone)] |
19 | pub struct NotSupportedError { |
20 | _marker: (), |
21 | } |
22 | |
23 | /// The error type for when the OS cannot perform the requested operation. |
24 | #[derive (Debug)] |
25 | pub struct OsError { |
26 | line: u32, |
27 | file: &'static str, |
28 | error: platform_impl::OsError, |
29 | } |
30 | |
31 | /// A general error that may occur while running the Winit event loop |
32 | #[derive (Debug)] |
33 | pub enum EventLoopError { |
34 | /// The operation is not supported by the backend. |
35 | NotSupported(NotSupportedError), |
36 | /// The OS cannot perform the operation. |
37 | Os(OsError), |
38 | /// The event loop can't be re-run while it's already running |
39 | AlreadyRunning, |
40 | /// The event loop can't be re-created. |
41 | RecreationAttempt, |
42 | /// Application has exit with an error status. |
43 | ExitFailure(i32), |
44 | } |
45 | |
46 | impl From<OsError> for EventLoopError { |
47 | fn from(value: OsError) -> Self { |
48 | Self::Os(value) |
49 | } |
50 | } |
51 | |
52 | impl NotSupportedError { |
53 | #[inline ] |
54 | #[allow (dead_code)] |
55 | pub(crate) fn new() -> NotSupportedError { |
56 | NotSupportedError { _marker: () } |
57 | } |
58 | } |
59 | |
60 | impl OsError { |
61 | #[allow (dead_code)] |
62 | pub(crate) fn new(line: u32, file: &'static str, error: platform_impl::OsError) -> OsError { |
63 | OsError { line, file, error } |
64 | } |
65 | } |
66 | |
67 | #[allow (unused_macros)] |
68 | macro_rules! os_error { |
69 | ($error:expr) => {{ |
70 | crate::error::OsError::new(line!(), file!(), $error) |
71 | }}; |
72 | } |
73 | |
74 | impl fmt::Display for OsError { |
75 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
76 | f.pad(&format!( |
77 | "os error at {}: {}: {}" , |
78 | self.file, self.line, self.error |
79 | )) |
80 | } |
81 | } |
82 | |
83 | impl fmt::Display for ExternalError { |
84 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
85 | match self { |
86 | ExternalError::NotSupported(e: &NotSupportedError) => e.fmt(f), |
87 | ExternalError::Ignored => write!(f, "Operation was ignored" ), |
88 | ExternalError::Os(e: &OsError) => e.fmt(f), |
89 | } |
90 | } |
91 | } |
92 | |
93 | impl fmt::Debug for NotSupportedError { |
94 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
95 | f.debug_struct(name:"NotSupportedError" ).finish() |
96 | } |
97 | } |
98 | |
99 | impl fmt::Display for NotSupportedError { |
100 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
101 | f.pad("the requested operation is not supported by Winit" ) |
102 | } |
103 | } |
104 | |
105 | impl fmt::Display for EventLoopError { |
106 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
107 | match self { |
108 | EventLoopError::AlreadyRunning => write!(f, "EventLoop is already running" ), |
109 | EventLoopError::RecreationAttempt => write!(f, "EventLoop can't be recreated" ), |
110 | EventLoopError::NotSupported(e: &NotSupportedError) => e.fmt(f), |
111 | EventLoopError::Os(e: &OsError) => e.fmt(f), |
112 | EventLoopError::ExitFailure(status: &i32) => write!(f, "Exit Failure: {status}" ), |
113 | } |
114 | } |
115 | } |
116 | |
117 | impl error::Error for OsError {} |
118 | impl error::Error for ExternalError {} |
119 | impl error::Error for NotSupportedError {} |
120 | impl error::Error for EventLoopError {} |
121 | |
122 | #[cfg (test)] |
123 | mod tests { |
124 | #![allow (clippy::redundant_clone)] |
125 | |
126 | use super::*; |
127 | |
128 | // Eat attributes for testing |
129 | #[test ] |
130 | fn ensure_fmt_does_not_panic() { |
131 | let _ = format!( |
132 | " {:?}, {}" , |
133 | NotSupportedError::new(), |
134 | NotSupportedError::new().clone() |
135 | ); |
136 | let _ = format!( |
137 | " {:?}, {}" , |
138 | ExternalError::NotSupported(NotSupportedError::new()), |
139 | ExternalError::NotSupported(NotSupportedError::new()) |
140 | ); |
141 | } |
142 | } |
143 | |