use std::{
error::Error as StdError,
fmt::{self, Display, Error as FormatError},
io::Error as IoError,
num::ParseIntError,
};
#[cfg(feature = "gateway")]
use async_tungstenite::tungstenite::error::Error as TungsteniteError;
#[cfg(feature = "http")]
use reqwest::{header::InvalidHeaderValue, Error as ReqwestError};
use serde_json::Error as JsonError;
use tracing::instrument;
#[cfg(feature = "client")]
use crate::client::ClientError;
#[cfg(feature = "gateway")]
use crate::gateway::GatewayError;
#[cfg(feature = "http")]
use crate::http::HttpError;
use crate::internal::prelude::*;
#[cfg(all(
feature = "gateway",
feature = "rustls_backend_marker",
not(feature = "native_tls_backend_marker")
))]
use crate::internal::ws_impl::RustlsError;
use crate::model::ModelError;
pub type Result<T> = StdResult<T, Error>;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
Decode(&'static str, Value),
Format(FormatError),
Io(IoError),
Json(JsonError),
Model(ModelError),
Num(ParseIntError),
ExceededLimit(String, u32),
NotInRange(&'static str, u64, u64, u64),
Other(&'static str),
Url(String),
#[cfg(feature = "client")]
Client(ClientError),
#[cfg(feature = "gateway")]
Gateway(GatewayError),
#[cfg(feature = "http")]
Http(Box<HttpError>),
#[cfg(all(
feature = "gateway",
feature = "rustls_backend_marker",
not(feature = "native_tls_backend_marker")
))]
Rustls(RustlsError),
#[cfg(feature = "gateway")]
Tungstenite(TungsteniteError),
}
impl From<FormatError> for Error {
fn from(e: FormatError) -> Error {
Error::Format(e)
}
}
#[cfg(feature = "gateway")]
impl From<GatewayError> for Error {
fn from(e: GatewayError) -> Error {
Error::Gateway(e)
}
}
impl From<IoError> for Error {
fn from(e: IoError) -> Error {
Error::Io(e)
}
}
impl From<JsonError> for Error {
fn from(e: JsonError) -> Error {
Error::Json(e)
}
}
impl From<ParseIntError> for Error {
fn from(e: ParseIntError) -> Error {
Error::Num(e)
}
}
impl From<ModelError> for Error {
fn from(e: ModelError) -> Error {
Error::Model(e)
}
}
#[cfg(all(
feature = "gateway",
feature = "rustls_backend_marker",
not(feature = "native_tls_backend_marker")
))]
impl From<RustlsError> for Error {
fn from(e: RustlsError) -> Error {
Error::Rustls(e)
}
}
#[cfg(feature = "gateway")]
impl From<TungsteniteError> for Error {
fn from(e: TungsteniteError) -> Error {
Error::Tungstenite(e)
}
}
#[cfg(feature = "http")]
impl From<HttpError> for Error {
fn from(e: HttpError) -> Error {
Error::Http(Box::new(e))
}
}
#[cfg(feature = "http")]
impl From<InvalidHeaderValue> for Error {
fn from(e: InvalidHeaderValue) -> Error {
HttpError::InvalidHeader(e).into()
}
}
#[cfg(feature = "http")]
impl From<ReqwestError> for Error {
fn from(e: ReqwestError) -> Error {
HttpError::Request(e).into()
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Decode(msg, _) | Error::Other(msg) => f.write_str(msg),
Error::ExceededLimit(..) => f.write_str("Input exceeded a limit"),
Error::NotInRange(..) => f.write_str("Input is not in the specified range"),
Error::Format(inner) => fmt::Display::fmt(&inner, f),
Error::Io(inner) => fmt::Display::fmt(&inner, f),
Error::Json(inner) => fmt::Display::fmt(&inner, f),
Error::Model(inner) => fmt::Display::fmt(&inner, f),
Error::Num(inner) => fmt::Display::fmt(&inner, f),
Error::Url(msg) => f.write_str(&msg),
#[cfg(feature = "client")]
Error::Client(inner) => fmt::Display::fmt(&inner, f),
#[cfg(feature = "gateway")]
Error::Gateway(inner) => fmt::Display::fmt(&inner, f),
#[cfg(feature = "http")]
Error::Http(inner) => fmt::Display::fmt(&inner, f),
#[cfg(all(feature = "gateway", not(feature = "native_tls_backend_marker")))]
Error::Rustls(inner) => fmt::Display::fmt(&inner, f),
#[cfg(feature = "gateway")]
Error::Tungstenite(inner) => fmt::Display::fmt(&inner, f),
}
}
}
impl StdError for Error {
#[instrument]
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
Error::Format(inner) => Some(inner),
Error::Io(inner) => Some(inner),
Error::Json(inner) => Some(inner),
Error::Model(inner) => Some(inner),
Error::Num(inner) => Some(inner),
#[cfg(feature = "client")]
Error::Client(inner) => Some(inner),
#[cfg(feature = "gateway")]
Error::Gateway(inner) => Some(inner),
#[cfg(feature = "http")]
Error::Http(inner) => Some(inner),
#[cfg(all(
feature = "gateway",
feature = "rustls_backend_marker",
not(feature = "native_tls_backend_marker")
))]
Error::Rustls(inner) => Some(inner),
#[cfg(feature = "gateway")]
Error::Tungstenite(inner) => Some(inner),
_ => None,
}
}
}