use axum::{
extract::Request,
middleware::Next,
response::{IntoResponse, Response},
};
use quokka::extract::Session;
use crate::data::Toast;
pub const ADMIN_MESSAGES_SESSION_KEY: &str = "admin_toasts";
#[doc(hidden)]
#[tracing::instrument(skip_all)]
pub async fn toast_middleware(mut request: Request, next: Next) -> Response {
let toasts = request
.extensions_mut()
.get_mut::<Session>()
.and_then(|session| session.extensions.remove(ADMIN_MESSAGES_SESSION_KEY))
.and_then(|value| {
serde_json::from_value::<Vec<Toast>>(value)
.inspect_err(|error| tracing::error!(?error, "The session has a toast key, but the data is invalid. The data will be ignored and a new empty set will be inserted."))
.ok()
})
.unwrap_or_default();
let starting_session = request.extensions().get::<Session>().cloned();
request.extensions_mut().insert(toasts);
let mut response = next.run(request).await;
let response_session = response
.extensions_mut()
.remove::<Session>()
.or(starting_session)
.and_then(|mut session| {
if let Some(toasts) = response.extensions_mut().remove::<Vec<Toast>>() {
if let Err(error) = session.add_extension(ADMIN_MESSAGES_SESSION_KEY, toasts) {
tracing::error!(?error, "Unable to place new toasts to session");
}
}
Some(session)
});
(response_session, response).into_response()
}