1use actix_web::{
31 web::Json,
32 {HttpResponse, ResponseError},
33};
34use http::StatusCode;
35use std::fmt::Debug;
36
37use crate::ProblemDetails;
38
39#[cfg(feature = "json")]
40use crate::JsonProblemDetails;
41
42#[cfg(feature = "xml")]
43use crate::XmlProblemDetails;
44
45#[cfg(feature = "json")]
46impl<Ext> ResponseError for ProblemDetails<Ext>
47where
48 Ext: serde::Serialize + Clone + Send + Debug,
49{
50 fn status_code(&self) -> actix_web::http::StatusCode {
51 let status_code = self
53 .status
54 .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
55 .as_u16();
56 actix_web::http::StatusCode::from_u16(status_code)
57 .expect("Status code should be translatable")
58 }
59
60 fn error_response(&self) -> HttpResponse {
61 HttpResponse::build(self.status_code())
62 .content_type(JsonProblemDetails::<Ext>::CONTENT_TYPE)
63 .json(Json(self))
64 }
65}
66
67#[cfg(feature = "json")]
68impl<Ext> ResponseError for JsonProblemDetails<Ext>
69where
70 Ext: serde::Serialize + Clone + Send + Debug,
71{
72 fn error_response(&self) -> HttpResponse {
73 HttpResponse::build(self.0.status_code())
74 .content_type(JsonProblemDetails::<Ext>::CONTENT_TYPE)
75 .json(Json(&self.0))
76 }
77}
78
79#[cfg(feature = "xml")]
80impl<Ext> ResponseError for XmlProblemDetails<Ext>
81where
82 Ext: serde::Serialize + Clone + Send + Debug,
83{
84 fn error_response(&self) -> HttpResponse {
85 let content = match self.to_body_string() {
86 Ok(xml) => xml,
87 Err(_) => return HttpResponse::InternalServerError().into(),
88 };
89
90 HttpResponse::build(self.0.status_code())
91 .content_type(XmlProblemDetails::<Ext>::CONTENT_TYPE)
92 .body(content)
93 }
94}