use std::error;
use std::fmt;
use url::Url;
pub type Result<T> = std::result::Result<T, GleifError>;
#[derive(Debug)]
pub enum GleifError {
ReqwestError(reqwest::Error),
ReqwestMiddlewareError(reqwest_middleware::Error),
UrlParseError(url::ParseError),
SerdeError(serde_json::Error),
IoError(std::io::Error),
ResponseError(ResponseContent),
ParseError {
kind: ParseErrorKind,
message: String,
},
}
#[derive(Debug, Clone)]
pub struct ResponseContent {
pub status: reqwest::StatusCode,
pub content: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParseErrorKind {
Field,
Value,
}
impl fmt::Display for GleifError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (module, e) = match self {
GleifError::ReqwestError(e) => ("reqwest", e.to_string()),
GleifError::ReqwestMiddlewareError(e) => ("reqwest-middleware", e.to_string()),
GleifError::UrlParseError(e) => ("url", e.to_string()),
GleifError::SerdeError(e) => ("serde", e.to_string()),
GleifError::IoError(e) => ("IO", e.to_string()),
GleifError::ResponseError(e) => ("response", format!("status code {}", e.status)),
GleifError::ParseError { kind, message } => match kind {
ParseErrorKind::Field => ("field", message.to_owned()),
ParseErrorKind::Value => ("value", message.to_owned()),
},
};
write!(f, "error in {module}: {e}")
}
}
impl error::Error for GleifError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
GleifError::ReqwestError(e) => Some(e),
GleifError::ReqwestMiddlewareError(e) => Some(e),
GleifError::SerdeError(e) => Some(e),
GleifError::IoError(e) => Some(e),
GleifError::UrlParseError(e) => Some(e),
GleifError::ParseError { .. } | GleifError::ResponseError(_) => None,
}
}
}
impl From<reqwest::Error> for GleifError {
fn from(e: reqwest::Error) -> Self {
GleifError::ReqwestError(e)
}
}
impl From<reqwest_middleware::Error> for GleifError {
fn from(e: reqwest_middleware::Error) -> Self {
GleifError::ReqwestMiddlewareError(e)
}
}
impl From<url::ParseError> for GleifError {
fn from(e: url::ParseError) -> Self {
GleifError::UrlParseError(e)
}
}
impl From<serde_json::Error> for GleifError {
fn from(e: serde_json::Error) -> Self {
GleifError::SerdeError(e)
}
}
impl From<std::io::Error> for GleifError {
fn from(e: std::io::Error) -> Self {
GleifError::IoError(e)
}
}
impl GleifError {
#[must_use]
pub fn url(&self) -> Option<&Url> {
match self {
GleifError::ReqwestError(inner) => inner.url(),
GleifError::ReqwestMiddlewareError(inner) => inner.url(),
_ => None,
}
}
#[must_use]
pub fn url_mut(&mut self) -> Option<&mut Url> {
match self {
GleifError::ReqwestError(inner) => inner.url_mut(),
GleifError::ReqwestMiddlewareError(inner) => inner.url_mut(),
_ => None,
}
}
#[must_use]
pub fn with_url(self, url: Url) -> Self {
match self {
GleifError::ReqwestError(inner) => GleifError::ReqwestError(inner.with_url(url)),
GleifError::ReqwestMiddlewareError(inner) => {
GleifError::ReqwestMiddlewareError(inner.with_url(url))
}
_ => self,
}
}
#[must_use]
pub fn without_url(self) -> Self {
match self {
GleifError::ReqwestError(inner) => GleifError::ReqwestError(inner.without_url()),
GleifError::ReqwestMiddlewareError(inner) => {
GleifError::ReqwestMiddlewareError(inner.without_url())
}
_ => self,
}
}
#[must_use]
pub fn is_middleware(&self) -> bool {
match self {
GleifError::ReqwestMiddlewareError(inner) => inner.is_middleware(),
_ => false,
}
}
#[must_use]
pub fn is_builder(&self) -> bool {
match self {
GleifError::ReqwestMiddlewareError(inner) => inner.is_builder(),
_ => false,
}
}
#[must_use]
pub fn is_redirect(&self) -> bool {
match self {
GleifError::ReqwestError(inner) => inner.is_redirect(),
GleifError::ReqwestMiddlewareError(inner) => inner.is_redirect(),
_ => false,
}
}
#[must_use]
pub fn is_status(&self) -> bool {
match self {
GleifError::ReqwestError(inner) => inner.is_status(),
GleifError::ReqwestMiddlewareError(inner) => inner.is_status(),
GleifError::ResponseError(_) => true,
_ => false,
}
}
#[must_use]
pub fn is_timeout(&self) -> bool {
match self {
GleifError::ReqwestError(inner) => inner.is_timeout(),
GleifError::ReqwestMiddlewareError(inner) => inner.is_timeout(),
_ => false,
}
}
#[must_use]
pub fn is_request(&self) -> bool {
match self {
GleifError::ReqwestError(inner) => inner.is_request(),
GleifError::ReqwestMiddlewareError(inner) => inner.is_request(),
_ => false,
}
}
#[must_use]
pub fn is_connect(&self) -> bool {
match self {
GleifError::ReqwestError(inner) => inner.is_connect(),
GleifError::ReqwestMiddlewareError(inner) => inner.is_connect(),
_ => false,
}
}
#[must_use]
pub fn is_body(&self) -> bool {
match self {
GleifError::ReqwestError(inner) => inner.is_body(),
GleifError::ReqwestMiddlewareError(inner) => inner.is_body(),
_ => false,
}
}
#[must_use]
pub fn is_decode(&self) -> bool {
match self {
GleifError::ReqwestError(inner) => inner.is_decode(),
GleifError::ReqwestMiddlewareError(inner) => inner.is_decode(),
GleifError::ParseError { .. } => true,
_ => false,
}
}
#[must_use]
pub fn status(&self) -> Option<reqwest::StatusCode> {
match self {
GleifError::ReqwestError(inner) => inner.status(),
GleifError::ReqwestMiddlewareError(inner) => inner.status(),
GleifError::ResponseError(resp) => Some(resp.status),
_ => None,
}
}
}