1 | //! Glutin error handling. |
2 | |
3 | use std::fmt; |
4 | |
5 | /// A specialized [`Result`] type for graphics operations. |
6 | pub type Result<T> = std::result::Result<T, Error>; |
7 | |
8 | /// The error type for all the graphics platform operations. |
9 | #[derive (Debug, Clone)] |
10 | pub struct Error { |
11 | /// The raw code of the underlying error. |
12 | raw_code: Option<i64>, |
13 | |
14 | /// The raw message from the os in case it could be obtained. |
15 | raw_os_message: Option<String>, |
16 | |
17 | /// The simplified error kind to handle mathing. |
18 | kind: ErrorKind, |
19 | } |
20 | |
21 | impl Error { |
22 | #[allow (dead_code)] |
23 | pub(crate) fn new( |
24 | raw_code: Option<i64>, |
25 | raw_os_message: Option<String>, |
26 | kind: ErrorKind, |
27 | ) -> Self { |
28 | Self { raw_code, raw_os_message, kind } |
29 | } |
30 | |
31 | /// Helper to check that error is [`ErrorKind::NotSupported`]. |
32 | #[inline ] |
33 | pub fn not_supported(&self) -> bool { |
34 | matches!(&self.kind, ErrorKind::NotSupported(_)) |
35 | } |
36 | |
37 | /// The underlying error kind. |
38 | #[inline ] |
39 | pub fn error_kind(&self) -> ErrorKind { |
40 | self.kind |
41 | } |
42 | |
43 | /// The underlying raw code in case it's present. |
44 | #[inline ] |
45 | pub fn raw_code(&self) -> Option<i64> { |
46 | self.raw_code |
47 | } |
48 | } |
49 | |
50 | impl fmt::Display for Error { |
51 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
52 | if let Some(raw_code: i64) = self.raw_code { |
53 | write!(f, "[ {raw_code:x}] " )?; |
54 | } |
55 | |
56 | let msg: &str = if let Some(raw_os_message: &String) = self.raw_os_message.as_ref() { |
57 | raw_os_message |
58 | } else { |
59 | self.kind.as_str() |
60 | }; |
61 | |
62 | write!(f, " {msg}" ) |
63 | } |
64 | } |
65 | |
66 | impl std::error::Error for Error {} |
67 | |
68 | /// Build an error with just a kind. |
69 | impl From<ErrorKind> for Error { |
70 | fn from(kind: ErrorKind) -> Self { |
71 | Error { raw_code: None, raw_os_message: None, kind } |
72 | } |
73 | } |
74 | |
75 | /// A list specifying general categoires of native platform graphics interface |
76 | /// errors. |
77 | #[derive (Clone, Copy, Debug, Hash, PartialEq, Eq)] |
78 | pub enum ErrorKind { |
79 | /// The requested display wasn't found or some required symbol in it was |
80 | /// missing. |
81 | NotFound, |
82 | |
83 | /// Failed to perform resource initialization. |
84 | InitializationFailed, |
85 | |
86 | /// Can't access a requested resource. |
87 | /// |
88 | /// For example when trying to make a context current while it's current on |
89 | /// another thread. |
90 | BadAccess, |
91 | |
92 | /// An operation could not be completed, because it failed to allocate |
93 | /// enough memory. |
94 | OutOfMemory, |
95 | |
96 | /// An recognized attribute value was passed. |
97 | BadAttribute, |
98 | |
99 | /// The context is no longer valid. |
100 | BadContext, |
101 | |
102 | /// The context is in bad state. |
103 | BadContextState, |
104 | |
105 | /// Invalid config was passed. |
106 | BadConfig, |
107 | |
108 | /// The current surface of the calling thread is no longer valid. |
109 | BadCurrentSurface, |
110 | |
111 | /// The display is no longer valid. |
112 | BadDisplay, |
113 | |
114 | /// The surface is invalid. |
115 | BadSurface, |
116 | |
117 | /// The pbuffer is invalid. |
118 | BadPbuffer, |
119 | |
120 | /// The pixmap is invalid. |
121 | BadPixmap, |
122 | |
123 | /// Arguments are inconsistent. For example when shared contexts are not |
124 | /// compatible. |
125 | BadMatch, |
126 | |
127 | /// One or more argument values are invalid. |
128 | BadParameter, |
129 | |
130 | /// Bad native pixmap was provided. |
131 | BadNativePixmap, |
132 | |
133 | /// Bad native window was provided. |
134 | BadNativeWindow, |
135 | |
136 | /// The context was lost. |
137 | ContextLost, |
138 | |
139 | /// The operation is not supported by the platform. |
140 | NotSupported(&'static str), |
141 | |
142 | /// The misc error that can't be classified occurred. |
143 | Misc, |
144 | } |
145 | |
146 | impl ErrorKind { |
147 | pub(crate) fn as_str(&self) -> &'static str { |
148 | use ErrorKind::*; |
149 | match *self { |
150 | NotFound => "not found" , |
151 | InitializationFailed => "initialization failed" , |
152 | BadAccess => "access to the resource failed" , |
153 | OutOfMemory => "out of memory" , |
154 | BadAttribute => "an anrecougnized attribute or attribute value was passed" , |
155 | BadContext => "argument does not name a valid context" , |
156 | BadContextState => "the context is in a bad state" , |
157 | BadConfig => "argument does not name a valid config" , |
158 | BadCurrentSurface => "the current surface of the calling thread is no longer valid" , |
159 | BadDisplay => "argument does not name a valid display" , |
160 | BadSurface => "argument does not name a valid surface" , |
161 | BadPbuffer => "argument does not name a valid pbuffer" , |
162 | BadPixmap => "argument does not name a valid pixmap" , |
163 | BadMatch => "arguments are inconsistance" , |
164 | BadParameter => "one or more argument values are invalid" , |
165 | BadNativePixmap => "argument does not refer to a valid native pixmap" , |
166 | BadNativeWindow => "argument does not refer to a valid native window" , |
167 | ContextLost => "context loss" , |
168 | NotSupported(reason) => reason, |
169 | Misc => "misc platform error" , |
170 | } |
171 | } |
172 | } |
173 | |
174 | impl fmt::Display for ErrorKind { |
175 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
176 | f.write_str(self.as_str()) |
177 | } |
178 | } |
179 | |