diff --git a/Cargo.toml b/Cargo.toml index a62b4ba..c22979f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,4 +26,3 @@ trust-dns-proto = "0.7" xmpp-parsers = "0.13" idna = "0.1" quick-xml = "0.13" -derive-error = "0.0.4" diff --git a/src/error.rs b/src/error.rs index d8b2063..68a1412 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,7 +11,7 @@ use xmpp_parsers::Error as ParsersError; use xmpp_parsers::sasl::DefinedCondition as SaslDefinedCondition; /// Top-level error type -#[derive(Debug, Error)] +#[derive(Debug)] pub enum Error { /// I/O error Io(IoError), @@ -32,8 +32,53 @@ pub enum Error { InvalidState, } +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::Idna => write!(fmt, "IDNA error"), + Error::Protocol(e) => write!(fmt, "protocol error: {}", e), + Error::Auth(e) => write!(fmt, "authentication error: {}", e), + Error::Tls(e) => write!(fmt, "TLS error: {}", e), + Error::Disconnected => write!(fmt, "disconnected"), + Error::InvalidState => write!(fmt, "invalid state"), + } + } +} + +impl From for Error { + fn from(e: IoError) -> Self { + Error::Io(e) + } +} + +impl From for Error { + fn from(e: ConnecterError) -> Self { + Error::Connection(e) + } +} + +impl From for Error { + fn from(e: ProtocolError) -> Self { + Error::Protocol(e) + } +} + +impl From for Error { + fn from(e: AuthError) -> Self { + Error::Auth(e) + } +} + +impl From for Error { + fn from(e: TlsError) -> Self { + Error::Tls(e) + } +} + /// Causes for stream parsing errors -#[derive(Debug, Error)] +#[derive(Debug)] pub enum ParserError { /// Encoding error Utf8(Utf8Error), @@ -42,7 +87,24 @@ pub enum ParserError { /// Illegal `` ShortTag, /// Required by `impl Decoder` - IO(IoError), + Io(IoError), +} + +impl fmt::Display for ParserError { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match self { + ParserError::Utf8(e) => write!(fmt, "UTF-8 error: {}", e), + ParserError::Parse(e) => write!(fmt, "parse error: {}", e), + ParserError::ShortTag => write!(fmt, "short tag"), + ParserError::Io(e) => write!(fmt, "IO error: {}", e), + } + } +} + +impl From for ParserError { + fn from(e: IoError) -> Self { + ParserError::Io(e) + } } impl From for Error { @@ -71,12 +133,11 @@ impl fmt::Display for ParseError { } /// XMPP protocol-level error -#[derive(Debug, Error)] +#[derive(Debug)] pub enum ProtocolError { /// XML parser error Parser(ParserError), /// Error with expected stanza schema - #[error(non_std)] Parsers(ParsersError), /// No TLS available NoTls, @@ -92,22 +153,57 @@ pub enum ProtocolError { 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 "), + ProtocolError::NoStreamId => write!(fmt, "no id attribute in "), + ProtocolError::InvalidToken => write!(fmt, "encountered an unexpected XML token"), + ProtocolError::InvalidStreamStart => write!(fmt, "unexpected "), + } + } +} + +impl From for ProtocolError { + fn from(e: ParserError) -> Self { + ProtocolError::Parser(e) + } +} + +impl From for ProtocolError { + fn from(e: ParsersError) -> Self { + ProtocolError::Parsers(e) + } +} + /// Authentication error -#[derive(Debug, Error)] +#[derive(Debug)] pub enum AuthError { /// No matching SASL mechanism available NoMechanism, /// Local SASL implementation error - #[error(no_from, non_std, msg_embedded)] Sasl(String), /// Failure from server - #[error(non_std)] Fail(SaslDefinedCondition), /// Component authentication failure - #[error(no_from)] ComponentFail, } +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"), + } + } +} + /// Error establishing connection #[derive(Debug)] pub enum ConnecterError { diff --git a/src/lib.rs b/src/lib.rs index 07ae878..2bd823e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,9 +2,6 @@ //! XMPP implementation with asynchronous I/O using Tokio. -#[macro_use] -extern crate derive_error; - mod starttls; mod stream_start; pub mod xmpp_codec;