use std::fmt::{self, Display, Formatter};
#[derive(Eq, Hash, PartialEq, Debug, Clone, Copy)]
pub enum StatusCode {
Ok = 200,
Created = 201,
Accepted = 202,
NoContent = 204,
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
RequestTimeout = 408,
LengthRequired = 411,
UnsupportedMediaType = 415,
IAmATeapot = 418,
TooManyRequests = 429,
InternalServerError = 500,
NotImplemented = 501,
ServiceUnavailable = 503,
GatewayTimeout = 504,
HttpVersionNotSupported = 505,
}
impl StatusCode {
pub(super) fn get_message(&self) -> &str {
match self {
Self::Ok => "OK",
Self::Created => "Created",
Self::Accepted => "Accepted",
Self::NoContent => "No Content",
Self::BadRequest => "Bad Request",
Self::Unauthorized => "Unauthorized",
Self::Forbidden => "Forbidden",
Self::NotFound => "Not Found",
Self::MethodNotAllowed => "Method Not Allowed",
Self::RequestTimeout => "Request Timeout",
Self::LengthRequired => "Length Required",
Self::UnsupportedMediaType => "Unsupported Media Type",
Self::IAmATeapot => "I'm A Teapot",
Self::TooManyRequests => "Too Many Requests",
Self::InternalServerError => "Internal Server Error",
Self::NotImplemented => "Not Implemented",
Self::ServiceUnavailable => "Service Unavailable",
Self::GatewayTimeout => "Gateway Timeout",
Self::HttpVersionNotSupported => "HTTP Version Not Supported",
}
}
}
impl Default for StatusCode {
fn default() -> Self {
Self::Ok
}
}
impl TryFrom<&str> for StatusCode {
type Error = ParseStatusCodeError;
fn try_from(code: &str) -> Result<Self, Self::Error> {
let num = code.parse().unwrap_or(0);
Self::try_from(num)
}
}
impl TryFrom<u16> for StatusCode {
type Error = ParseStatusCodeError;
fn try_from(code: u16) -> Result<Self, Self::Error> {
Self::try_from(&code)
}
}
impl From<&StatusCode> for u16 {
fn from(code: &StatusCode) -> u16 {
*code as u16
}
}
impl TryFrom<&u16> for StatusCode {
type Error = ParseStatusCodeError;
fn try_from(status_code: &u16) -> Result<Self, Self::Error> {
match status_code {
200 => Ok(Self::Ok),
201 => Ok(Self::Created),
202 => Ok(Self::Accepted),
204 => Ok(Self::NoContent),
400 => Ok(Self::BadRequest),
401 => Ok(Self::Unauthorized),
403 => Ok(Self::Forbidden),
404 => Ok(Self::NotFound),
405 => Ok(Self::MethodNotAllowed),
408 => Ok(Self::RequestTimeout),
411 => Ok(Self::LengthRequired),
415 => Ok(Self::UnsupportedMediaType),
418 => Ok(Self::IAmATeapot),
429 => Ok(Self::TooManyRequests),
500 => Ok(Self::InternalServerError),
501 => Ok(Self::NotImplemented),
503 => Ok(Self::ServiceUnavailable),
504 => Ok(Self::GatewayTimeout),
505 => Ok(Self::HttpVersionNotSupported),
_ => Err(ParseStatusCodeError),
}
}
}
impl Display for StatusCode {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", *self as u16)
}
}
#[derive(Debug)]
pub struct ParseStatusCodeError;
impl Display for ParseStatusCodeError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Invalid status code for HTTP response")
}
}