1use std::error::Error;
2use std::fmt::{self, Display};
3
4use crate::data_transfer::DataTransferId;
5
6#[derive(Debug)]
9#[non_exhaustive]
10pub enum EventLoopError {
11 RecreationAttempt,
13 ExitFailure(i32),
15 Os(OsError),
17 NotSupported(NotSupportedError),
19}
20
21impl fmt::Display for EventLoopError {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 Self::RecreationAttempt => {
25 write!(
26 f,
27 "EventLoop can't be recreated, only a single instance of it is supported (for \
28 cross-platform compatibility)"
29 )
30 },
31 Self::Os(err) => err.fmt(f),
32 Self::ExitFailure(status) => write!(f, "Exit Failure: {status}"),
33 Self::NotSupported(err) => err.fmt(f),
34 }
35 }
36}
37
38impl Error for EventLoopError {
39 fn source(&self) -> Option<&(dyn Error + 'static)> {
40 if let Self::Os(err) = self { err.source() } else { None }
41 }
42}
43
44impl From<OsError> for EventLoopError {
45 fn from(value: OsError) -> Self {
46 Self::Os(value)
47 }
48}
49
50impl From<NotSupportedError> for EventLoopError {
51 fn from(value: NotSupportedError) -> Self {
52 Self::NotSupported(value)
53 }
54}
55
56#[derive(Debug)]
58#[non_exhaustive]
59pub enum CreateWindowError {
60 PopupNotSupported,
62 InvalidAttribute(InvalidInput),
64 Os(OsError),
66}
67
68impl Display for CreateWindowError {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 match self {
71 Self::PopupNotSupported => write!(f, "WindowType::Popup is not supported"),
72 Self::InvalidAttribute(InvalidInput { reason }) => {
73 write!(f, "Invalid WindowAttributes: {reason}")
74 },
75 Self::Os(err) => err.fmt(f),
76 }
77 }
78}
79impl Error for CreateWindowError {
80 fn source(&self) -> Option<&(dyn Error + 'static)> {
81 if let Self::Os(err) = self { err.source() } else { None }
82 }
83}
84
85impl From<InvalidInput> for CreateWindowError {
86 fn from(value: InvalidInput) -> Self {
87 Self::InvalidAttribute(value)
88 }
89}
90
91impl From<OsError> for CreateWindowError {
92 fn from(value: OsError) -> Self {
93 Self::Os(value)
94 }
95}
96
97#[derive(Debug)]
99#[non_exhaustive]
100pub enum TransferError {
101 NotSupported(NotSupportedError),
103 UnknownTransfer(DataTransferId),
105 Failed,
107 Os(OsError),
109}
110
111impl Display for TransferError {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 match self {
114 Self::NotSupported(err) => err.fmt(f),
115 Self::UnknownTransfer(id) => {
116 write!(f, "Unknown data transfer with ID {}", id.into_raw())
117 },
118 Self::Failed => write!(f, "Transfer request failed"),
119 Self::Os(err) => err.fmt(f),
120 }
121 }
122}
123impl Error for TransferError {
124 fn source(&self) -> Option<&(dyn Error + 'static)> {
125 if let Self::Os(err) = self { err.source() } else { None }
126 }
127}
128impl From<NotSupportedError> for TransferError {
129 fn from(value: NotSupportedError) -> Self {
130 Self::NotSupported(value)
131 }
132}
133
134impl From<OsError> for TransferError {
135 fn from(value: OsError) -> Self {
136 Self::Os(value)
137 }
138}
139
140#[derive(Debug)]
142#[non_exhaustive]
143pub enum CustomCursorError {
144 NotSupported,
146 UnsupportedSource,
148 Os(OsError),
150}
151
152impl Display for CustomCursorError {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 match self {
155 Self::NotSupported => write!(f, "create_custom_cursor is not supported"),
156 Self::UnsupportedSource => {
157 write!(f, "the provided CustomCursorSource is not supported")
158 },
159 Self::Os(err) => err.fmt(f),
160 }
161 }
162}
163impl Error for CustomCursorError {
164 fn source(&self) -> Option<&(dyn Error + 'static)> {
165 if let Self::Os(err) = self { err.source() } else { None }
166 }
167}
168
169impl From<OsError> for CustomCursorError {
170 fn from(value: OsError) -> Self {
171 Self::Os(value)
172 }
173}
174
175#[derive(Debug)]
177#[non_exhaustive]
178pub enum RequestError {
179 NotSupported(NotSupportedError),
181 Os(OsError),
183}
184
185impl Display for RequestError {
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 match self {
188 Self::NotSupported(err) => err.fmt(f),
189 Self::Os(err) => err.fmt(f),
190 }
191 }
192}
193impl Error for RequestError {
194 fn source(&self) -> Option<&(dyn Error + 'static)> {
195 if let Self::Os(err) = self { err.source() } else { None }
196 }
197}
198
199impl From<NotSupportedError> for RequestError {
200 fn from(value: NotSupportedError) -> Self {
201 Self::NotSupported(value)
202 }
203}
204
205impl From<OsError> for RequestError {
206 fn from(value: OsError) -> Self {
207 Self::Os(value)
208 }
209}
210
211#[derive(Debug)]
213pub struct InvalidInput {
214 reason: &'static str,
216}
217
218impl InvalidInput {
219 pub const fn new(reason: &'static str) -> Self {
220 Self { reason }
221 }
222}
223
224impl fmt::Display for InvalidInput {
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 write!(f, "Invalid input: {}", self.reason)
227 }
228}
229impl Error for InvalidInput {}
230
231#[derive(Debug)]
233pub struct NotSupportedError {
234 reason: &'static str,
236}
237
238impl NotSupportedError {
239 pub const fn new(reason: &'static str) -> Self {
240 Self { reason }
241 }
242}
243
244impl fmt::Display for NotSupportedError {
245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246 write!(f, "Operation is not supported: {}", self.reason)
247 }
248}
249impl Error for NotSupportedError {}
250
251#[derive(Debug)]
253pub struct InternalError {
254 source: &'static str,
255}
256
257impl InternalError {
258 pub const fn new(source: &'static str) -> Self {
259 Self { source }
260 }
261}
262
263impl fmt::Display for InternalError {
264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265 write!(f, "Internal error: {}", self.source)
266 }
267}
268impl Error for InternalError {}
269
270#[derive(Debug)]
272pub struct OsError {
273 line: u32,
274 file: &'static str,
275 error: Box<dyn Error + Send + Sync + 'static>,
276}
277
278impl OsError {
279 pub fn new(
280 line: u32,
281 file: &'static str,
282 error: impl Into<Box<dyn Error + Send + Sync + 'static>>,
283 ) -> Self {
284 Self { line, file, error: error.into() }
285 }
286}
287
288impl Display for OsError {
289 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290 f.pad(&format!("os error at {}:{}: {}", self.file, self.line, self.error))
291 }
292}
293impl Error for OsError {
294 fn source(&self) -> Option<&(dyn Error + 'static)> {
295 Some(self.error.as_ref())
296 }
297}
298
299#[allow(unused_macros)]
300macro_rules! os_error {
301 ($error:expr) => {{ crate::error::OsError::new(line!(), file!(), $error) }};
302}