89 lines
2.2 KiB
Rust
89 lines
2.2 KiB
Rust
use super::{
|
|
accept::{parse_accept, ResponseType},
|
|
error::{ErrorInfo, Result},
|
|
};
|
|
use askama::Template;
|
|
use askama_axum::IntoResponse;
|
|
use axum::{
|
|
http::{header::ACCEPT, Request, StatusCode},
|
|
middleware::Next,
|
|
response::Html,
|
|
Json,
|
|
};
|
|
use serde_json::json;
|
|
|
|
pub type HandlerResponse = Result<askama_axum::Response>;
|
|
|
|
struct Response {
|
|
html: String,
|
|
json: serde_json::Value,
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "error.html")]
|
|
struct ErrorTemplate {
|
|
status: String,
|
|
message: String,
|
|
}
|
|
|
|
pub fn reply<T: Template>(json: serde_json::Value, html: T) -> HandlerResponse {
|
|
let mut response = StatusCode::OK.into_response();
|
|
response.extensions_mut().insert(Response {
|
|
html: html.render()?,
|
|
json,
|
|
});
|
|
Ok(response)
|
|
}
|
|
|
|
/// Handles the multiple return type system of staxman.
|
|
/// Handlers might return an Error or a Response object, this will intercept
|
|
/// those and return them as either JSON or HTML depending on the Accept header.
|
|
pub async fn response_interceptor<B>(
|
|
request: Request<B>,
|
|
next: Next<B>,
|
|
) -> axum::response::Response {
|
|
let accept = request
|
|
.headers()
|
|
.get(&ACCEPT)
|
|
.map(parse_accept)
|
|
.unwrap_or_else(|| ResponseType::Html);
|
|
|
|
let mut response = next.run(request).await;
|
|
|
|
if let Some(ErrorInfo {
|
|
status,
|
|
code,
|
|
message,
|
|
}) = response.extensions_mut().remove::<ErrorInfo>()
|
|
{
|
|
match accept {
|
|
ResponseType::Json => {
|
|
return (status, Json(json!({"code": code, "message": message}))).into_response();
|
|
}
|
|
_ => {
|
|
return (
|
|
status,
|
|
ErrorTemplate {
|
|
status: status.to_string(),
|
|
message,
|
|
},
|
|
)
|
|
.into_response();
|
|
}
|
|
}
|
|
}
|
|
|
|
if let Some(Response { html, json }) = response.extensions_mut().remove::<Response>() {
|
|
match accept {
|
|
ResponseType::Json => {
|
|
return Json(json).into_response();
|
|
}
|
|
_ => {
|
|
return Html(html).into_response();
|
|
}
|
|
}
|
|
}
|
|
|
|
response
|
|
}
|