beatrice 0.3.2

This library was renamed to Servlin.
Documentation
use crate::head::HeadError;
use crate::Response;
use safina_timer::{DeadlineError, DeadlineExceeded};
use std::io::ErrorKind;

#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
pub enum HttpError {
    AlreadyGotBody,
    BodyNotAvailable,
    BodyNotRead,
    BodyNotUtf8,
    BodyTooLong,
    CacheDirNotConfigured,
    Disconnected,
    DuplicateContentLengthHeader,
    DuplicateContentTypeHeader,
    DuplicateTransferEncodingHeader,
    ErrorReadingFile(ErrorKind, String),
    ErrorReadingResponseBody(ErrorKind, String),
    ErrorSavingFile(ErrorKind, String),
    HandlerDeadlineExceeded,
    HeadTooLong,
    InvalidContentLength,
    MalformedCookieHeader,
    MalformedHeaderLine,
    MalformedPath,
    MalformedRequestLine,
    MissingRequestLine,
    ResponseAlreadySent,
    ResponseNotSent,
    TimerThreadNotStarted,
    Truncated,
    UnsupportedProtocol,
    UnsupportedTransferEncoding,
    UnwritableResponse,
}
impl HttpError {
    #[must_use]
    #[allow(clippy::needless_pass_by_value)]
    pub fn error_reading_file(e: std::io::Error) -> Self {
        HttpError::ErrorReadingFile(e.kind(), e.to_string())
    }

    #[must_use]
    #[allow(clippy::needless_pass_by_value)]
    pub fn error_reading_response_body(e: std::io::Error) -> Self {
        HttpError::ErrorReadingResponseBody(e.kind(), e.to_string())
    }

    #[must_use]
    #[allow(clippy::needless_pass_by_value)]
    pub fn error_saving_file(e: std::io::Error) -> Self {
        HttpError::ErrorSavingFile(e.kind(), e.to_string())
    }

    #[must_use]
    pub fn is_server_error(&self) -> bool {
        match self {
            HttpError::AlreadyGotBody
            | HttpError::BodyNotAvailable
            | HttpError::BodyNotRead
            | HttpError::CacheDirNotConfigured
            | HttpError::DuplicateContentLengthHeader
            | HttpError::DuplicateContentTypeHeader
            | HttpError::DuplicateTransferEncodingHeader
            | HttpError::ErrorReadingFile(..)
            | HttpError::ErrorReadingResponseBody(..)
            | HttpError::ErrorSavingFile(..)
            | HttpError::HandlerDeadlineExceeded
            | HttpError::ResponseAlreadySent
            | HttpError::ResponseNotSent
            | HttpError::UnwritableResponse => true,
            HttpError::BodyNotUtf8
            | HttpError::BodyTooLong
            | HttpError::Disconnected
            | HttpError::HeadTooLong
            | HttpError::InvalidContentLength
            | HttpError::MalformedCookieHeader
            | HttpError::MalformedHeaderLine
            | HttpError::MalformedPath
            | HttpError::MalformedRequestLine
            | HttpError::MissingRequestLine
            | HttpError::TimerThreadNotStarted
            | HttpError::Truncated
            | HttpError::UnsupportedProtocol
            | HttpError::UnsupportedTransferEncoding => false,
        }
    }

    #[must_use]
    pub fn description(&self) -> String {
        match self {
            HttpError::AlreadyGotBody => "HttpError::AlreadyGotBody".to_string(),
            HttpError::BodyNotAvailable => "HttpError::BodyNotAvailable".to_string(),
            HttpError::BodyNotRead => "HttpError::BodyNotRead".to_string(),
            HttpError::BodyNotUtf8 => "HttpError::BodyNotUtf8".to_string(),
            HttpError::BodyTooLong => "HttpError::BodyTooLong".to_string(),
            HttpError::CacheDirNotConfigured => "HttpError::CacheDirNotConfigured".to_string(),
            HttpError::DuplicateContentLengthHeader => {
                "HttpError::DuplicateContentLengthHeader".to_string()
            }
            HttpError::DuplicateContentTypeHeader => {
                "HttpError::DuplicateContentTypeHeader".to_string()
            }
            HttpError::DuplicateTransferEncodingHeader => {
                "HttpError::DuplicateTransferEncodingHeader".to_string()
            }
            HttpError::Disconnected => "HttpError::Disconnected".to_string(),
            HttpError::ErrorReadingFile(kind, s) => {
                format!("HttpError::ErrorReadingFile: {:?}: {}", kind, s)
            }
            HttpError::ErrorReadingResponseBody(kind, s) => {
                format!("HttpError::ErrorReadingResponseBody: {:?}: {}", kind, s)
            }
            HttpError::ErrorSavingFile(kind, s) => {
                format!("HttpError::ErrorSavingFile: {:?}: {}", kind, s)
            }
            HttpError::HandlerDeadlineExceeded => "HttpError::HandlerDeadlineExceeded".to_string(),
            HttpError::HeadTooLong => "HttpError::HeadTooLong".to_string(),
            HttpError::InvalidContentLength => "HttpError::InvalidContentLength".to_string(),
            HttpError::MalformedCookieHeader => "HttpError::MalformedCookieHeader".to_string(),
            HttpError::MalformedHeaderLine => "HttpError::MalformedHeaderLine".to_string(),
            HttpError::MalformedPath => "HttpError::MalformedPath".to_string(),
            HttpError::MalformedRequestLine => "HttpError::MalformedRequestLine".to_string(),
            HttpError::MissingRequestLine => "HttpError::MissingRequestLine".to_string(),
            HttpError::ResponseAlreadySent => "HttpError::ResponseAlreadySent".to_string(),
            HttpError::ResponseNotSent => "HttpError::ResponseNotSent".to_string(),
            HttpError::TimerThreadNotStarted => "HttpError::TimerThreadNotStarted".to_string(),
            HttpError::Truncated => "HttpError::Truncated".to_string(),
            HttpError::UnsupportedProtocol => "HttpError::UnsupportedProtocol".to_string(),
            HttpError::UnsupportedTransferEncoding => {
                "HttpError::UnsupportedTransferEncoding".to_string()
            }
            HttpError::UnwritableResponse => "HttpError::UnwritableResponse".to_string(),
        }
    }
}
impl From<HeadError> for HttpError {
    fn from(e: HeadError) -> Self {
        match e {
            HeadError::Truncated => HttpError::Truncated,
            HeadError::MissingRequestLine => HttpError::MissingRequestLine,
            HeadError::MalformedRequestLine => HttpError::MalformedRequestLine,
            HeadError::MalformedPath => HttpError::MalformedPath,
            HeadError::UnsupportedProtocol => HttpError::UnsupportedProtocol,
            HeadError::MalformedHeader => HttpError::MalformedHeaderLine,
        }
    }
}
impl From<HttpError> for Response {
    fn from(e: HttpError) -> Self {
        match e {
            HttpError::BodyNotUtf8
            | HttpError::InvalidContentLength
            | HttpError::MalformedCookieHeader
            | HttpError::MalformedHeaderLine
            | HttpError::MalformedPath
            | HttpError::MalformedRequestLine
            | HttpError::MissingRequestLine
            | HttpError::Truncated
            | HttpError::UnsupportedTransferEncoding => Response::text(400, e.description()),
            HttpError::Disconnected => Response::drop_connection(),
            HttpError::BodyTooLong => Response::text(413, "Uploaded data is too big."),
            HttpError::HeadTooLong => Response::text(431, e.description()),
            HttpError::UnsupportedProtocol => Response::text(505, e.description()),
            HttpError::AlreadyGotBody
            | HttpError::BodyNotAvailable
            | HttpError::BodyNotRead
            | HttpError::CacheDirNotConfigured
            | HttpError::DuplicateContentLengthHeader
            | HttpError::DuplicateContentTypeHeader
            | HttpError::DuplicateTransferEncodingHeader
            | HttpError::ErrorReadingFile(..)
            | HttpError::ErrorReadingResponseBody(..)
            | HttpError::ErrorSavingFile(..)
            | HttpError::HandlerDeadlineExceeded
            | HttpError::ResponseAlreadySent
            | HttpError::ResponseNotSent
            | HttpError::TimerThreadNotStarted
            | HttpError::UnwritableResponse => Response::text(500, "Internal server error"),
        }
    }
}
impl From<DeadlineExceeded> for HttpError {
    fn from(_: DeadlineExceeded) -> Self {
        HttpError::HandlerDeadlineExceeded
    }
}
impl From<DeadlineError> for HttpError {
    fn from(e: DeadlineError) -> Self {
        match e {
            DeadlineError::TimerThreadNotStarted => HttpError::TimerThreadNotStarted,
            DeadlineError::DeadlineExceeded => HttpError::HandlerDeadlineExceeded,
        }
    }
}