1//! Glutin error handling.
2
3use std::fmt;
4
5/// A specialized [`Result`] type for graphics operations.
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// The error type for all the graphics platform operations.
9#[derive(Debug, Clone)]
10pub 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
21impl 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
50impl 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
66impl std::error::Error for Error {}
67
68/// Build an error with just a kind.
69impl 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)]
78pub 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
146impl 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
174impl fmt::Display for ErrorKind {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 f.write_str(self.as_str())
177 }
178}
179