1use std::{error, fmt};
2
3use crate::platform_impl;
4
5// TODO: Rename
6/// An error that may be generated when requesting Winit state
7#[derive(Debug)]
8pub 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)]
19pub struct NotSupportedError {
20 _marker: (),
21}
22
23/// The error type for when the OS cannot perform the requested operation.
24#[derive(Debug)]
25pub 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)]
33pub 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
46impl From<OsError> for EventLoopError {
47 fn from(value: OsError) -> Self {
48 Self::Os(value)
49 }
50}
51
52impl NotSupportedError {
53 #[inline]
54 #[allow(dead_code)]
55 pub(crate) fn new() -> NotSupportedError {
56 NotSupportedError { _marker: () }
57 }
58}
59
60impl 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)]
68macro_rules! os_error {
69 ($error:expr) => {{
70 crate::error::OsError::new(line!(), file!(), $error)
71 }};
72}
73
74impl 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
83impl 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
93impl 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
99impl 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
105impl 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
117impl error::Error for OsError {}
118impl error::Error for ExternalError {}
119impl error::Error for NotSupportedError {}
120impl error::Error for EventLoopError {}
121
122#[cfg(test)]
123mod 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