xcb_rust_connection/helpers/
errors.rs

1use alloc::string::String;
2use core::fmt::Formatter;
3
4use tiny_std::Error as StdError;
5use xcb_rust_protocol::proto::xproto::{SetupAuthenticate, SetupFailed};
6use xcb_rust_protocol::Error;
7
8/// An error that occurred while connecting to an X11 server
9#[derive(Debug)]
10#[non_exhaustive]
11pub enum ConnectError {
12    /// An unknown error occurred.
13    ///
14    /// One situation were this error is used when libxcb indicates an error that does not match
15    /// any of the defined error conditions. Thus, libxcb is violating its own API (or new error
16    /// cases were defined, but are not yet handled by x11rb).
17    UnknownError,
18
19    /// Out of memory.
20    ///
21    /// This is `XCB_CONN_CLOSED_MEM_INSUFFICIENT`.
22    InsufficientMemory,
23
24    /// Error during parsing of display string.
25    ///
26    /// This is `XCB_CONN_CLOSED_PARSE_ERR`.
27    DisplayParsingError,
28
29    /// Server does not have a screen matching the display.
30    ///
31    /// This is `XCB_CONN_CLOSED_INVALID_SCREEN`.
32    InvalidScreen,
33
34    /// Invalid ID mask provided by the server.
35    ///
36    /// The value of `resource_id_mask` in the `Setup` provided by the server was zero.
37    ZeroIdMask,
38
39    /// The server rejected the connection with a `SetupAuthenticate` message.
40    SetupAuthenticate(SetupAuthenticate),
41
42    /// The server rejected the connection with a `SetupFailed` message.
43    SetupFailed(SetupFailed),
44
45    /// The client did not receive enough data from the server to complete
46    /// the handshake.
47    Incomplete {
48        /// The number of bytes that were expected.
49        expected: usize,
50        /// The number of bytes that were received.
51        received: usize,
52    },
53
54    StdError(StdError),
55    Syscall(rusl::Error),
56
57    Proto(xcb_rust_protocol::Error),
58    BadValue,
59    Io(&'static str),
60}
61
62impl From<xcb_rust_protocol::Error> for ConnectError {
63    fn from(e: Error) -> Self {
64        Self::Proto(e)
65    }
66}
67
68impl From<StdError> for ConnectError {
69    fn from(e: StdError) -> Self {
70        Self::StdError(e)
71    }
72}
73
74impl From<rusl::Error> for ConnectError {
75    fn from(e: rusl::Error) -> Self {
76        Self::Syscall(e)
77    }
78}
79
80impl core::fmt::Display for ConnectError {
81    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
82        fn display(
83            f: &mut core::fmt::Formatter<'_>,
84            prefix: &str,
85            value: &[u8],
86        ) -> core::fmt::Result {
87            match core::str::from_utf8(value).ok() {
88                Some(value) => write!(f, "{prefix}: '{value}'"),
89                None => write!(f, "{prefix}: {value:?} [message is not utf8]"),
90            }
91        }
92        match self {
93            ConnectError::UnknownError => write!(f, "Unknown connection error"),
94            ConnectError::InsufficientMemory => write!(f, "Insufficient memory"),
95            ConnectError::DisplayParsingError => write!(f, "Display parsing error"),
96            ConnectError::InvalidScreen => write!(f, "Invalid screen"),
97            ConnectError::ZeroIdMask => write!(f, "XID mask was zero"),
98            ConnectError::SetupFailed(err) => display(f, "X11 setup failed", &err.reason),
99            ConnectError::SetupAuthenticate(err) => {
100                display(f, "X11 authentication failed", &err.reason)
101            }
102            ConnectError::Incomplete { .. } => write!(f, "Incomplete packet"),
103            ConnectError::StdError(e) => write!(f, "Syscall: {e}"),
104            ConnectError::BadValue => write!(f, "Tried to parse a bad value"),
105            ConnectError::Proto(p) => write!(f, "{p}"),
106            ConnectError::Syscall(e) => write!(f, "Syscall: {e}"),
107            ConnectError::Io(e) => write!(f, "Delegate io failed: {e}"),
108        }
109    }
110}
111
112/// An error that occurred on an already established X11 connection
113#[derive(Debug, Clone)]
114#[non_exhaustive]
115pub enum ConnectionError {
116    /// An unknown error occurred.
117    ///
118    /// One situation were this error is used when libxcb indicates an error that does not match
119    /// any of the defined error conditions. Thus, libxcb is violating its own API (or new error
120    /// cases were defined, but are not yet handled by x11rb).
121    UnknownError(String),
122
123    /// An X11 extension was not supported by the server.
124    ///
125    /// This corresponds to `XCB_CONN_CLOSED_EXT_NOTSUPPORTED`.
126    UnsupportedExtension(String),
127
128    /// A request larger than the maximum request length was sent.
129    ///
130    /// This corresponds to `XCB_CONN_CLOSED_REQ_LEN_EXCEED`.
131    MaximumRequestLengthExceeded(String),
132
133    /// Out of memory.
134    ///
135    /// This is `XCB_CONN_CLOSED_MEM_INSUFFICIENT`.
136    InsufficientMemory,
137
138    Protocol(xcb_rust_protocol::Error),
139
140    StdErr(StdError),
141    Syscall(rusl::Error),
142
143    Id(IdError),
144    Io(&'static str),
145}
146
147impl From<xcb_rust_protocol::Error> for ConnectionError {
148    #[inline]
149    fn from(e: Error) -> Self {
150        Self::Protocol(e)
151    }
152}
153
154impl From<rusl::Error> for ConnectionError {
155    fn from(e: rusl::Error) -> Self {
156        Self::Syscall(e)
157    }
158}
159
160impl From<StdError> for ConnectionError {
161    fn from(e: StdError) -> Self {
162        Self::StdErr(e)
163    }
164}
165
166impl From<IdError> for ConnectionError {
167    #[inline]
168    fn from(e: IdError) -> Self {
169        Self::Id(e)
170    }
171}
172
173impl core::fmt::Display for ConnectionError {
174    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
175        match self {
176            ConnectionError::UnknownError(s) => write!(f, "Unknown connection error {s}"),
177            ConnectionError::UnsupportedExtension(s) => write!(f, "Unsupported extension {s}"),
178            ConnectionError::InsufficientMemory => write!(f, "Insufficient memory"),
179            ConnectionError::MaximumRequestLengthExceeded(s) => {
180                write!(f, "Maximum request length exceeded {s}")
181            }
182            ConnectionError::Protocol(e) => {
183                write!(f, "Protocol error {e}")
184            }
185            ConnectionError::Id(id) => {
186                write!(f, "IdError {id}")
187            }
188            ConnectionError::StdErr(s) => {
189                write!(f, "Std call failed {s:?}")
190            }
191            ConnectionError::Syscall(s) => {
192                write!(f, "Syscall failed {s:?}")
193            }
194            ConnectionError::Io(e) => {
195                write!(f, "Delegate io failed {e}")
196            }
197        }
198    }
199}
200
201#[derive(Debug, Copy, Clone)]
202pub enum IdError {
203    IdsExhausted,
204}
205
206impl core::fmt::Display for IdError {
207    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
208        match self {
209            IdError::IdsExhausted => f.write_str("Ids exhausted"),
210        }
211    }
212}