quokka-admin 0.1.0

An admin panel for quokka
Documentation
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";

/// This middleware reads and puts the [Toast]s as an extension to the request. It will also add new ones to the session on response
#[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()
}