athene 2.0.4

A simple and lightweight rust web framework based on hyper
Documentation
use crate::{responder::Responder, response::Builder};
use hyper::{header::InvalidHeaderValue, StatusCode};
use std::fmt::{Debug, Formatter};

#[derive(thiserror::Error, Debug)]
pub enum InternalError {
    #[error("Http: {0}")]
    Http(hyper::http::Error),
    #[error("Hyper: {0}")]
    Hyper(hyper::Error),
    #[error("ToStr: {0}")]
    ToStr(hyper::header::ToStrError),
}

#[derive(thiserror::Error)]
pub enum Error {
    #[error("Internal: {0}")]
    Internal(#[from] InternalError),

    #[error("Io: {0}")]
    Io(#[from] std::io::Error),

    #[error("Boxed: {0}")]
    Boxed(Box<dyn std::error::Error + Send + Sync + 'static>),

    #[error("Hyper: {0}")]
    Hyper(hyper::Error),

    #[error("Other: {0}")]
    Other(String),

    #[error("Response StatusCode `{0}`")]
    Status(StatusCode),

    #[error("Response StatusCode `{0}`,Response Body: {1}")]
    Response(StatusCode, serde_json::Value),

    #[error("FromUtf8Error: {0}")]
    FromUtf8Error(#[from] std::string::FromUtf8Error),

    #[error("SerdeJson: {0}")]
    SerdeJson(#[from] serde_json::error::Error),

    #[error("SerdeUrlDe: {0}")]
    SerdeUrlDe(#[from] serde_urlencoded::de::Error),

    #[error("SerdeUrlSer: {0}")]
    SerdeUrlSer(#[from] serde_urlencoded::ser::Error),

    #[cfg(feature = "websocket")]
    #[error("WebSocket: {0}")]
    WebSocket(#[from] tokio_tungstenite::tungstenite::Error),

    #[cfg(feature = "multipart")]
    #[error("An multer error: {0}")]
    Multer(#[from] multer::Error),

    #[cfg(feature = "msgpack")]
    #[error("could not deserialize the body of a request or response from MessagePack")]
    MsgpackDeserialization(#[source] rmp_serde::decode::Error),

    #[error("Missing parameter `{0}` (is_query: {1})")]
    MissingParameter(String, bool),

    #[error("Invalid parameter `{0}` (is_query: {1})")]
    InvalidParameter(String, bool),

    #[cfg(feature = "validate")]
    #[cfg_attr(docsrs, doc(cfg(feature = "validate")))]
    #[error("ValidationErrors: {0}")]
    ValidationErrors(#[from] validator::ValidationErrors),

    #[error("AddrParseError: {0}")]
    AddrParseError(#[from] std::net::AddrParseError),
}

impl Debug for Error {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Internal(d) => std::fmt::Debug::fmt(d, f),
            Self::Io(d) => std::fmt::Debug::fmt(d, f),
            Self::Boxed(d) => std::fmt::Debug::fmt(d, f),
            Self::Hyper(d) => std::fmt::Debug::fmt(d, f),
            Self::Other(d) => std::fmt::Debug::fmt(d, f),
            Self::Status(d) => std::fmt::Debug::fmt(d, f),
            Self::Response(_, d) => std::fmt::Debug::fmt(d, f),
            Self::FromUtf8Error(d) => std::fmt::Debug::fmt(d, f),
            Self::SerdeJson(d) => std::fmt::Debug::fmt(d, f),
            Self::SerdeUrlDe(d) => std::fmt::Debug::fmt(d, f),
            Self::SerdeUrlSer(d) => std::fmt::Debug::fmt(d, f),
            #[cfg(feature = "websocket")]
            Self::WebSocket(d) => std::fmt::Debug::fmt(d, f),
            #[cfg(feature = "multipart")]
            Self::Multer(d) => std::fmt::Debug::fmt(d, f),
            #[cfg(feature = "msgpack")]
            Self::MsgpackDeserialization(d) => std::fmt::Debug::fmt(d, f),
            Self::MissingParameter(d, _) => std::fmt::Debug::fmt(d, f),
            Self::InvalidParameter(d, _) => std::fmt::Debug::fmt(d, f),
            #[cfg(feature = "validate")]
            Self::ValidationErrors(d) => std::fmt::Debug::fmt(d, f),
            Self::AddrParseError(d) => std::fmt::Debug::fmt(d, f),
        }
    }
}

impl Error {
    #[inline]
    pub(crate) fn response_builder(self, builder: Builder) -> Builder {
        match self {
            Self::Internal(e) => builder.status(500).text(e.to_string()),
            Self::Io(e) => builder.status(500).text(e.to_string()),
            Self::Boxed(e) => builder.status(500).text(e.to_string()),
            Self::Hyper(e) => builder.status(500).text(e.to_string()),
            Self::Other(e) => builder.status(500).text(e.to_string()),
            Self::Status(s) => builder.status(s),
            Self::Response(s, e) => builder.status(s).text(e.to_string()),
            Self::FromUtf8Error(e) => builder.status(400).text(e.to_string()),
            Self::SerdeJson(e) => builder.status(400).text(e.to_string()),
            Self::SerdeUrlDe(e) => builder.status(400).text(e.to_string()),
            Self::SerdeUrlSer(e) => builder.status(400).text(e.to_string()),
            #[cfg(feature = "websocket")]
            Self::WebSocket(e) => builder.status(400).text(e.to_string()),
            #[cfg(feature = "multipart")]
            Self::Multer(e) => builder.status(400).text(e.to_string()),
            #[cfg(feature = "msgpack")]
            Self::MsgpackDeserialization(e) => builder.status(400).text(e.to_string()),
            Self::MissingParameter(e, _) => builder.status(400).text(e.to_string()),
            Self::InvalidParameter(e, _) => builder.status(400).text(e.to_string()),
            #[cfg(feature = "validate")]
            Self::ValidationErrors(e) => builder.status(400).text(e.to_string()),
            Self::AddrParseError(e) => builder.status(400).text(e.to_string()),
        }
    }
}

impl From<hyper::http::Error> for Error {
    #[inline]
    fn from(e: hyper::http::Error) -> Self {
        Error::Internal(InternalError::Http(e))
    }
}

impl From<InvalidHeaderValue> for Error {
    #[inline]
    fn from(e: InvalidHeaderValue) -> Self {
        Error::Internal(InternalError::Http(hyper::http::Error::from(e)))
    }
}

impl From<hyper::Error> for Error {
    #[inline]
    fn from(e: hyper::Error) -> Self {
        Error::Internal(InternalError::Hyper(e))
    }
}

impl From<hyper::header::ToStrError> for Error {
    #[inline]
    fn from(e: hyper::header::ToStrError) -> Self {
        Error::Internal(InternalError::ToStr(e))
    }
}

impl From<std::convert::Infallible> for Error {
    fn from(e: std::convert::Infallible) -> Self {
        Self::Boxed(Box::new(e))
    }
}

impl Responder for Error {
    #[allow(unused_variables)]
    #[inline]
    fn response(self, builder: Builder) -> Builder {
        self.response_builder(builder)
    }
}