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