glutin/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//! Glutin error handling.

use std::fmt;

/// A specialized [`Result`] type for graphics operations.
pub type Result<T> = std::result::Result<T, Error>;

/// The error type for all the graphics platform operations.
#[derive(Debug, Clone)]
pub struct Error {
    /// The raw code of the underlying error.
    raw_code: Option<i64>,

    /// The raw message from the os in case it could be obtained.
    raw_os_message: Option<String>,

    /// The simplified error kind to handle matching.
    kind: ErrorKind,
}

impl Error {
    #[allow(dead_code)]
    pub(crate) fn new(
        raw_code: Option<i64>,
        raw_os_message: Option<String>,
        kind: ErrorKind,
    ) -> Self {
        Self { raw_code, raw_os_message, kind }
    }

    /// Helper to check that error is [`ErrorKind::NotSupported`].
    #[inline]
    pub fn not_supported(&self) -> bool {
        matches!(&self.kind, ErrorKind::NotSupported(_))
    }

    /// The underlying error kind.
    #[inline]
    pub fn error_kind(&self) -> ErrorKind {
        self.kind
    }

    /// The underlying raw code in case it's present.
    #[inline]
    pub fn raw_code(&self) -> Option<i64> {
        self.raw_code
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(raw_code) = self.raw_code {
            write!(f, "[{raw_code:x}] ")?;
        }

        let msg = if let Some(raw_os_message) = self.raw_os_message.as_ref() {
            raw_os_message
        } else {
            self.kind.as_str()
        };

        write!(f, "{msg}")
    }
}

impl std::error::Error for Error {}

/// Build an error with just a kind.
impl From<ErrorKind> for Error {
    fn from(kind: ErrorKind) -> Self {
        Error { raw_code: None, raw_os_message: None, kind }
    }
}

/// A list specifying general categoires of native platform graphics interface
/// errors.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum ErrorKind {
    /// The requested display wasn't found or some required symbol in it was
    /// missing.
    NotFound,

    /// Failed to perform resource initialization.
    InitializationFailed,

    /// Can't access a requested resource.
    ///
    /// For example when trying to make a context current while it's current on
    /// another thread.
    BadAccess,

    /// An operation could not be completed, because it failed to allocate
    /// enough memory.
    OutOfMemory,

    /// An recognized attribute value was passed.
    BadAttribute,

    /// The context is no longer valid.
    BadContext,

    /// The context is in bad state.
    BadContextState,

    /// Invalid config was passed.
    BadConfig,

    /// The current surface of the calling thread is no longer valid.
    BadCurrentSurface,

    /// The display is no longer valid.
    BadDisplay,

    /// The surface is invalid.
    BadSurface,

    /// The pbuffer is invalid.
    BadPbuffer,

    /// The pixmap is invalid.
    BadPixmap,

    /// Arguments are inconsistent. For example when shared contexts are not
    /// compatible.
    BadMatch,

    /// One or more argument values are invalid.
    BadParameter,

    /// Bad native pixmap was provided.
    BadNativePixmap,

    /// Bad native window was provided.
    BadNativeWindow,

    /// The context was lost.
    ContextLost,

    /// The operation is not supported by the platform.
    NotSupported(&'static str),

    /// The misc error that can't be classified occurred.
    Misc,
}

impl ErrorKind {
    pub(crate) fn as_str(&self) -> &'static str {
        use ErrorKind::*;
        match *self {
            NotFound => "not found",
            InitializationFailed => "initialization failed",
            BadAccess => "access to the resource failed",
            OutOfMemory => "out of memory",
            BadAttribute => "an unrecognized attribute or attribute value was passed",
            BadContext => "argument does not name a valid context",
            BadContextState => "the context is in a bad state",
            BadConfig => "argument does not name a valid config",
            BadCurrentSurface => "the current surface of the calling thread is no longer valid",
            BadDisplay => "argument does not name a valid display",
            BadSurface => "argument does not name a valid surface",
            BadPbuffer => "argument does not name a valid pbuffer",
            BadPixmap => "argument does not name a valid pixmap",
            BadMatch => "arguments are inconsistent",
            BadParameter => "one or more argument values are invalid",
            BadNativePixmap => "argument does not refer to a valid native pixmap",
            BadNativeWindow => "argument does not refer to a valid native window",
            ContextLost => "context loss",
            NotSupported(reason) => reason,
            Misc => "misc platform error",
        }
    }
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}