#[cfg(test)]
mod tests;
pub mod problem;
pub use problem::problem;
use crate::header::Header;
use crate::request::Request;
use crate::response::{Response, STATUS_CODE_REASON_PHRASE};
pub trait IntoResponse {
fn into_response(self) -> Response;
}
impl IntoResponse for Response {
fn into_response(self) -> Response {
self
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum AppError {
BadRequest(String),
Unauthorized,
Forbidden,
NotFound(String),
Conflict(String),
UnprocessableEntity(String),
TooManyRequests,
PayloadTooLarge(String),
Internal(String),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, body_str) = match &self {
AppError::BadRequest(msg) => (STATUS_CODE_REASON_PHRASE.n400_bad_request, msg.as_str()),
AppError::Unauthorized => (STATUS_CODE_REASON_PHRASE.n401_unauthorized, "Unauthorized"),
AppError::Forbidden => (STATUS_CODE_REASON_PHRASE.n403_forbidden, "Forbidden"),
AppError::NotFound(msg) => (STATUS_CODE_REASON_PHRASE.n404_not_found, msg.as_str()),
AppError::Conflict(msg) => (STATUS_CODE_REASON_PHRASE.n409_conflict, msg.as_str()),
AppError::UnprocessableEntity(msg) => (STATUS_CODE_REASON_PHRASE.n422_unprocessable_entity, msg.as_str()),
AppError::TooManyRequests => (STATUS_CODE_REASON_PHRASE.n429_too_many_requests, "Too Many Requests"),
AppError::PayloadTooLarge(msg) => (STATUS_CODE_REASON_PHRASE.n413_payload_too_large, msg.as_str()),
AppError::Internal(msg) => (STATUS_CODE_REASON_PHRASE.n500_internal_server_error, msg.as_str()),
};
let detail = match &self {
AppError::Unauthorized | AppError::Forbidden | AppError::TooManyRequests => "",
_ => body_str,
};
let dummy = Request {
method: "GET".to_string(),
request_uri: "/".to_string(),
http_version: "HTTP/1.1".to_string(),
headers: vec![],
body: Default::default(),
};
problem::with_headers(status, detail, body_str, Some(Header::get_header_list(&dummy)))
}
}