use crate::protocol::xproto::{SetupAuthenticate, SetupFailed};
use crate::x11_utils::X11Error;
#[cfg(feature = "dl-libxcb")]
#[derive(Debug, Clone)]
pub enum LibxcbLoadError {
OpenLibError(std::ffi::OsString, String),
GetSymbolError(Vec<u8>, String),
}
#[cfg(feature = "dl-libxcb")]
impl std::fmt::Display for LibxcbLoadError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LibxcbLoadError::OpenLibError(lib_name, e) => {
write!(f, "failed to open library {:?}: {}", lib_name, e)
}
LibxcbLoadError::GetSymbolError(symbol, e) => write!(
f,
"failed to get symbol \"{}\": {}",
symbol
.iter()
.map(|&c| std::ascii::escape_default(c))
.flatten()
.map(char::from)
.collect::<String>(),
e,
),
}
}
}
#[cfg(feature = "dl-libxcb")]
impl std::error::Error for LibxcbLoadError {}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ParseError {
InsufficientData,
ConversionFailed,
InvalidExpression,
InvalidValue,
MissingFileDescriptors,
}
impl std::error::Error for ParseError {}
impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ParseError::InsufficientData => write!(f, "Insufficient data was provided"),
ParseError::ConversionFailed => {
write!(f, "A value conversion failed due to out of range data")
}
ParseError::InvalidExpression => write!(
f,
"An expression could not be computed, e.g. due to overflow"
),
ParseError::InvalidValue => {
write!(f, "A value could not be parsed into an enumeration")
}
ParseError::MissingFileDescriptors => write!(f, "Missing file descriptors"),
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ConnectError {
UnknownError,
ParseError(ParseError),
InsufficientMemory,
DisplayParsingError,
InvalidScreen,
IOError(std::io::Error),
ZeroIDMask,
SetupAuthenticate(SetupAuthenticate),
SetupFailed(SetupFailed),
}
impl std::error::Error for ConnectError {}
impl std::fmt::Display for ConnectError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn display(
f: &mut std::fmt::Formatter<'_>,
prefix: &str,
value: &[u8],
) -> std::fmt::Result {
match std::str::from_utf8(value).ok() {
Some(value) => write!(f, "{}: '{}'", prefix, value),
None => write!(f, "{}: {:?} [message is not utf8]", prefix, value),
}
}
match self {
ConnectError::UnknownError => write!(f, "Unknown connection error"),
ConnectError::InsufficientMemory => write!(f, "Insufficient memory"),
ConnectError::DisplayParsingError => write!(f, "Display parsing error"),
ConnectError::InvalidScreen => write!(f, "Invalid screen"),
ConnectError::ParseError(err) => err.fmt(f),
ConnectError::IOError(err) => err.fmt(f),
ConnectError::ZeroIDMask => write!(f, "XID mask was zero"),
ConnectError::SetupFailed(err) => display(f, "X11 setup failed", &err.reason),
ConnectError::SetupAuthenticate(err) => {
display(f, "X11 authentication failed", &err.reason)
}
}
}
}
impl From<ParseError> for ConnectError {
fn from(err: ParseError) -> Self {
ConnectError::ParseError(err)
}
}
impl From<std::io::Error> for ConnectError {
fn from(err: std::io::Error) -> Self {
ConnectError::IOError(err)
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ConnectionError {
UnknownError,
UnsupportedExtension,
MaximumRequestLengthExceeded,
FDPassingFailed,
ParseError(ParseError),
InsufficientMemory,
IOError(std::io::Error),
}
impl std::error::Error for ConnectionError {}
impl std::fmt::Display for ConnectionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ConnectionError::UnknownError => write!(f, "Unknown connection error"),
ConnectionError::UnsupportedExtension => write!(f, "Unsupported extension"),
ConnectionError::InsufficientMemory => write!(f, "Insufficient memory"),
ConnectionError::MaximumRequestLengthExceeded => {
write!(f, "Maximum request length exceeded")
}
ConnectionError::FDPassingFailed => write!(f, "FD passing failed"),
ConnectionError::ParseError(err) => err.fmt(f),
ConnectionError::IOError(err) => err.fmt(f),
}
}
}
impl From<ParseError> for ConnectionError {
fn from(err: ParseError) -> Self {
ConnectionError::ParseError(err)
}
}
impl From<std::io::Error> for ConnectionError {
fn from(err: std::io::Error) -> Self {
ConnectionError::IOError(err)
}
}
#[derive(Debug)]
pub enum ReplyError {
ConnectionError(ConnectionError),
X11Error(X11Error),
}
impl std::error::Error for ReplyError {}
impl std::fmt::Display for ReplyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ReplyError::ConnectionError(e) => write!(f, "{}", e),
ReplyError::X11Error(e) => write!(f, "X11 error {:?}", e),
}
}
}
impl From<ParseError> for ReplyError {
fn from(err: ParseError) -> Self {
Self::from(ConnectionError::from(err))
}
}
impl From<std::io::Error> for ReplyError {
fn from(err: std::io::Error) -> Self {
ConnectionError::from(err).into()
}
}
impl From<ConnectionError> for ReplyError {
fn from(err: ConnectionError) -> Self {
Self::ConnectionError(err)
}
}
impl From<X11Error> for ReplyError {
fn from(err: X11Error) -> Self {
Self::X11Error(err)
}
}
#[derive(Debug)]
pub enum ReplyOrIdError {
IdsExhausted,
ConnectionError(ConnectionError),
X11Error(X11Error),
}
impl std::fmt::Display for ReplyOrIdError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ReplyOrIdError::IdsExhausted => f.write_str("X11 IDs have been exhausted"),
ReplyOrIdError::ConnectionError(e) => write!(f, "{}", e),
ReplyOrIdError::X11Error(e) => write!(f, "X11 error {:?}", e),
}
}
}
impl std::error::Error for ReplyOrIdError {}
impl From<ParseError> for ReplyOrIdError {
fn from(err: ParseError) -> Self {
ConnectionError::from(err).into()
}
}
impl From<ConnectionError> for ReplyOrIdError {
fn from(err: ConnectionError) -> Self {
ReplyOrIdError::ConnectionError(err)
}
}
impl From<X11Error> for ReplyOrIdError {
fn from(err: X11Error) -> Self {
ReplyOrIdError::X11Error(err)
}
}
impl From<ReplyError> for ReplyOrIdError {
fn from(err: ReplyError) -> Self {
match err {
ReplyError::ConnectionError(err) => ReplyOrIdError::ConnectionError(err),
ReplyError::X11Error(err) => ReplyOrIdError::X11Error(err),
}
}
}