use http::StatusCode;
use crate::response::{JsonApiDocument, JsonApiError};
use std::fmt;
#[derive(Debug)]
pub struct JsonApiErrorResponse {
pub status: StatusCode,
pub errors: Vec<JsonApiError>,
}
impl fmt::Display for JsonApiErrorResponse {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"JSON:API Error ({}): {:?}",
self.status,
self.errors
.iter()
.map(|e| e.title.as_deref().unwrap_or("Unknown Error"))
.collect::<Vec<_>>()
)
}
}
impl std::error::Error for JsonApiErrorResponse {}
impl JsonApiErrorResponse {
pub fn new(status: StatusCode, errors: Vec<JsonApiError>) -> Self {
Self { status, errors }
}
pub fn to_document<T>(&self) -> JsonApiDocument<T> {
JsonApiDocument {
errors: Some(self.errors.clone()),
data: None,
included: None,
links: None,
meta: None,
jsonapi: None,
}
}
}
pub fn bad_request_error(title: &str, detail: &str) -> JsonApiErrorResponse {
let error = JsonApiError::builder()
.status("400")
.code("BAD_REQUEST")
.title(title)
.detail(detail)
.build();
JsonApiErrorResponse::new(StatusCode::BAD_REQUEST, vec![error])
}
pub fn internal_server_error(detail: &str) -> JsonApiErrorResponse {
let error = JsonApiError::builder()
.status("500")
.code("INTERNAL_SERVER_ERROR")
.title("Internal Server Error")
.detail(detail)
.build();
JsonApiErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, vec![error])
}
pub fn unauthorized_error(detail: &str) -> JsonApiErrorResponse {
let error = JsonApiError::builder()
.status("401")
.code("UNAUTHORIZED")
.title("Unauthorized")
.detail(detail)
.build();
JsonApiErrorResponse::new(StatusCode::UNAUTHORIZED, vec![error])
}
pub fn not_found_error(detail: &str) -> JsonApiErrorResponse {
let error = JsonApiError::builder()
.status("404")
.code("NOT_FOUND")
.title("Not Found")
.detail(detail)
.build();
JsonApiErrorResponse::new(StatusCode::NOT_FOUND, vec![error])
}
pub fn forbidden_error(detail: &str) -> JsonApiErrorResponse {
let error = JsonApiError::builder()
.status("403")
.code("FORBIDDEN")
.title("Forbidden")
.detail(detail)
.build();
JsonApiErrorResponse::new(StatusCode::FORBIDDEN, vec![error])
}
pub fn conflict_error(detail: &str) -> JsonApiErrorResponse {
let error = JsonApiError::builder()
.status("409")
.code("CONFLICT")
.title("Conflict")
.detail(detail)
.build();
JsonApiErrorResponse::new(StatusCode::CONFLICT, vec![error])
}