| 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-created. |
| 39 | RecreationAttempt, |
| 40 | /// Application has exit with an error status. |
| 41 | ExitFailure(i32), |
| 42 | } |
| 43 | |
| 44 | impl From<OsError> for EventLoopError { |
| 45 | fn from(value: OsError) -> Self { |
| 46 | Self::Os(value) |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | impl NotSupportedError { |
| 51 | #[inline ] |
| 52 | #[allow (dead_code)] |
| 53 | pub(crate) fn new() -> NotSupportedError { |
| 54 | NotSupportedError { _marker: () } |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | impl OsError { |
| 59 | #[allow (dead_code)] |
| 60 | pub(crate) fn new(line: u32, file: &'static str, error: platform_impl::OsError) -> OsError { |
| 61 | OsError { line, file, error } |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | #[allow (unused_macros)] |
| 66 | macro_rules! os_error { |
| 67 | ($error:expr) => {{ |
| 68 | crate::error::OsError::new(line!(), file!(), $error) |
| 69 | }}; |
| 70 | } |
| 71 | |
| 72 | impl fmt::Display for OsError { |
| 73 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 74 | f.pad(&format!("os error at {}: {}: {}" , self.file, self.line, self.error)) |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | impl fmt::Display for ExternalError { |
| 79 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 80 | match self { |
| 81 | ExternalError::NotSupported(e: &NotSupportedError) => e.fmt(f), |
| 82 | ExternalError::Ignored => write!(f, "Operation was ignored" ), |
| 83 | ExternalError::Os(e: &OsError) => e.fmt(f), |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | impl fmt::Debug for NotSupportedError { |
| 89 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 90 | f.debug_struct(name:"NotSupportedError" ).finish() |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | impl fmt::Display for NotSupportedError { |
| 95 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 96 | f.pad("the requested operation is not supported by Winit" ) |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | impl fmt::Display for EventLoopError { |
| 101 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 102 | match self { |
| 103 | EventLoopError::RecreationAttempt => write!(f, "EventLoop can't be recreated" ), |
| 104 | EventLoopError::NotSupported(e: &NotSupportedError) => e.fmt(f), |
| 105 | EventLoopError::Os(e: &OsError) => e.fmt(f), |
| 106 | EventLoopError::ExitFailure(status: &i32) => write!(f, "Exit Failure: {status}" ), |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | impl error::Error for OsError {} |
| 112 | impl error::Error for ExternalError {} |
| 113 | impl error::Error for NotSupportedError {} |
| 114 | impl error::Error for EventLoopError {} |
| 115 | |
| 116 | #[cfg (test)] |
| 117 | #[allow (clippy::redundant_clone)] |
| 118 | mod tests { |
| 119 | use super::*; |
| 120 | |
| 121 | // Eat attributes for testing |
| 122 | #[test ] |
| 123 | fn ensure_fmt_does_not_panic() { |
| 124 | let _ = format!("{:?}, {}" , NotSupportedError::new(), NotSupportedError::new().clone()); |
| 125 | let _ = format!( |
| 126 | "{:?}, {}" , |
| 127 | ExternalError::NotSupported(NotSupportedError::new()), |
| 128 | ExternalError::NotSupported(NotSupportedError::new()) |
| 129 | ); |
| 130 | } |
| 131 | } |
| 132 | |