use std::io::Error as IoError;
use std::sync::mpsc::RecvError;
use thiserror::Error;
use tokio::sync::mpsc::error::{SendError, TrySendError};
#[cfg(feature = "tls-rust")]
use tokio_rustls::webpki::InvalidDNSNameError;
use crate::proto::error::{MessageParseError, ProtocolError};
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, Error)]
pub enum Error {
#[error("an io error occurred")]
Io(#[source] IoError),
#[cfg(feature = "proxy")]
#[error("a proxy error occurred")]
Proxy(tokio_socks::Error),
#[cfg(feature = "tls-native")]
#[error("a TLS error occurred")]
Tls(#[source] native_tls::Error),
#[cfg(feature = "tls-rust")]
#[error("a DNS error occurred")]
Dns(#[source] InvalidDNSNameError),
#[error("a sync channel closed")]
SyncChannelClosed(#[source] RecvError),
#[error("an async channel closed")]
AsyncChannelClosed,
#[error("a oneshot channel closed")]
OneShotCanceled,
#[error("invalid config: {}", path)]
InvalidConfig {
path: String,
#[source]
cause: ConfigError,
},
#[error("invalid message: {}", string)]
InvalidMessage {
string: String,
#[source]
cause: MessageParseError,
},
#[error("mutex for a logged transport was poisoned")]
PoisonedLog,
#[error("connection reset: no ping response")]
PingTimeout,
#[error("unknown codec: {}", codec)]
UnknownCodec {
codec: String,
},
#[error("codec {} failed: {}", codec, data)]
CodecFailed {
codec: &'static str,
data: String,
},
#[error("none of the specified nicknames were usable")]
NoUsableNick,
#[error("stream has already been configured")]
StreamAlreadyConfigured,
}
#[derive(Debug, Error)]
pub enum ConfigError {
#[cfg(feature = "toml_config")]
#[error("invalid toml")]
InvalidToml(#[source] TomlError),
#[cfg(feature = "json_config")]
#[error("invalid json")]
InvalidJson(#[source] serde_json::Error),
#[cfg(feature = "yaml_config")]
#[error("invalid yaml")]
InvalidYaml(#[source] serde_yaml::Error),
#[error("config format disabled: {}", format)]
ConfigFormatDisabled {
format: &'static str,
},
#[error("config format unknown: {}", format)]
UnknownConfigFormat {
format: String,
},
#[error("missing format extension")]
MissingExtension,
#[error("nickname not specified")]
NicknameNotSpecified,
#[error("server not specified")]
ServerNotSpecified,
#[error("could not read file {}", file)]
FileMissing {
file: String,
},
}
#[cfg(feature = "toml_config")]
#[derive(Debug, Error)]
pub enum TomlError {
#[error("deserialization failed")]
Read(#[source] toml::de::Error),
#[error("serialization failed")]
Write(#[source] toml::ser::Error),
}
impl From<ProtocolError> for Error {
fn from(e: ProtocolError) -> Error {
match e {
ProtocolError::Io(e) => Error::Io(e),
ProtocolError::InvalidMessage { string, cause } => {
Error::InvalidMessage { string, cause }
}
}
}
}
impl From<IoError> for Error {
fn from(e: IoError) -> Error {
Error::Io(e)
}
}
#[cfg(feature = "proxy")]
impl From<tokio_socks::Error> for Error {
fn from(e: tokio_socks::Error) -> Error {
Error::Proxy(e)
}
}
#[cfg(feature = "tls-native")]
impl From<native_tls::Error> for Error {
fn from(e: native_tls::Error) -> Error {
Error::Tls(e)
}
}
#[cfg(feature = "tls-rust")]
impl From<InvalidDNSNameError> for Error {
fn from(e: InvalidDNSNameError) -> Error {
Error::Dns(e)
}
}
impl From<RecvError> for Error {
fn from(e: RecvError) -> Error {
Error::SyncChannelClosed(e)
}
}
impl<T> From<SendError<T>> for Error {
fn from(_: SendError<T>) -> Error {
Error::AsyncChannelClosed
}
}
impl<T> From<TrySendError<T>> for Error {
fn from(_: TrySendError<T>) -> Error {
Error::AsyncChannelClosed
}
}