#[cfg(feature = "dns")]
use hickory_resolver::{
error::ResolveError as DnsResolveError, proto::error::ProtoError as DnsProtoError,
};
use sasl::client::MechanismError as SaslMechanismError;
use std::error::Error as StdError;
use std::fmt;
use std::io::Error as IoError;
use std::net::AddrParseError;
use std::str::Utf8Error;
use xmpp_parsers::sasl::DefinedCondition as SaslDefinedCondition;
use xmpp_parsers::{jid::Error as JidParseError, Error as ParsersError};
use crate::connect::ServerConnectorError;
#[derive(Debug)]
pub enum Error {
Io(IoError),
JidParse(JidParseError),
Protocol(ProtocolError),
Auth(AuthError),
Disconnected,
InvalidState,
Fmt(fmt::Error),
Utf8(Utf8Error),
Connection(Box<dyn ServerConnectorError>),
#[cfg(feature = "dns")]
Dns(DnsProtoError),
#[cfg(feature = "dns")]
Resolve(DnsResolveError),
#[cfg(feature = "dns")]
Idna,
Addr(AddrParseError),
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Io(e) => write!(fmt, "IO error: {}", e),
Error::Connection(e) => write!(fmt, "connection error: {}", e),
Error::JidParse(e) => write!(fmt, "jid parse error: {}", e),
Error::Protocol(e) => write!(fmt, "protocol error: {}", e),
Error::Auth(e) => write!(fmt, "authentication error: {}", e),
Error::Disconnected => write!(fmt, "disconnected"),
Error::InvalidState => write!(fmt, "invalid state"),
Error::Fmt(e) => write!(fmt, "Fmt error: {}", e),
Error::Utf8(e) => write!(fmt, "Utf8 error: {}", e),
#[cfg(feature = "dns")]
Error::Dns(e) => write!(fmt, "{:?}", e),
#[cfg(feature = "dns")]
Error::Resolve(e) => write!(fmt, "{:?}", e),
#[cfg(feature = "dns")]
Error::Idna => write!(fmt, "IDNA error"),
Error::Addr(e) => write!(fmt, "Wrong network address: {e}"),
}
}
}
impl StdError for Error {}
impl From<IoError> for Error {
fn from(e: IoError) -> Self {
Error::Io(e)
}
}
impl<T: ServerConnectorError + 'static> From<T> for Error {
fn from(e: T) -> Self {
Error::Connection(Box::new(e))
}
}
impl From<JidParseError> for Error {
fn from(e: JidParseError) -> Self {
Error::JidParse(e)
}
}
impl From<ProtocolError> for Error {
fn from(e: ProtocolError) -> Self {
Error::Protocol(e)
}
}
impl From<AuthError> for Error {
fn from(e: AuthError) -> Self {
Error::Auth(e)
}
}
impl From<fmt::Error> for Error {
fn from(e: fmt::Error) -> Self {
Error::Fmt(e)
}
}
impl From<Utf8Error> for Error {
fn from(e: Utf8Error) -> Self {
Error::Utf8(e)
}
}
#[cfg(feature = "dns")]
impl From<idna::Errors> for Error {
fn from(_e: idna::Errors) -> Self {
Error::Idna
}
}
#[cfg(feature = "dns")]
impl From<DnsResolveError> for Error {
fn from(e: DnsResolveError) -> Error {
Error::Resolve(e)
}
}
#[cfg(feature = "dns")]
impl From<DnsProtoError> for Error {
fn from(e: DnsProtoError) -> Error {
Error::Dns(e)
}
}
impl From<AddrParseError> for Error {
fn from(e: AddrParseError) -> Error {
Error::Addr(e)
}
}
#[derive(Debug)]
pub enum ProtocolError {
Parser(minidom::Error),
Parsers(ParsersError),
NoTls,
InvalidBindResponse,
NoStreamNamespace,
NoStreamId,
InvalidToken,
InvalidStreamStart,
}
impl fmt::Display for ProtocolError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
ProtocolError::Parser(e) => write!(fmt, "XML parser error: {}", e),
ProtocolError::Parsers(e) => write!(fmt, "error with expected stanza schema: {}", e),
ProtocolError::NoTls => write!(fmt, "no TLS available"),
ProtocolError::InvalidBindResponse => {
write!(fmt, "invalid response to resource binding")
}
ProtocolError::NoStreamNamespace => {
write!(fmt, "no xmlns attribute in <stream:stream>")
}
ProtocolError::NoStreamId => write!(fmt, "no id attribute in <stream:stream>"),
ProtocolError::InvalidToken => write!(fmt, "encountered an unexpected XML token"),
ProtocolError::InvalidStreamStart => write!(fmt, "unexpected <stream:stream>"),
}
}
}
impl StdError for ProtocolError {}
impl From<minidom::Error> for ProtocolError {
fn from(e: minidom::Error) -> Self {
ProtocolError::Parser(e)
}
}
impl From<minidom::Error> for Error {
fn from(e: minidom::Error) -> Self {
ProtocolError::Parser(e).into()
}
}
impl From<ParsersError> for ProtocolError {
fn from(e: ParsersError) -> Self {
ProtocolError::Parsers(e)
}
}
#[derive(Debug)]
pub enum AuthError {
NoMechanism,
Sasl(SaslMechanismError),
Fail(SaslDefinedCondition),
ComponentFail,
}
impl StdError for AuthError {}
impl fmt::Display for AuthError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
AuthError::NoMechanism => write!(fmt, "no matching SASL mechanism available"),
AuthError::Sasl(s) => write!(fmt, "local SASL implementation error: {}", s),
AuthError::Fail(c) => write!(fmt, "failure from the server: {:?}", c),
AuthError::ComponentFail => write!(fmt, "component authentication failure"),
}
}
}