mae 0.3.12

Opinionated async Rust framework for building Mae-Technologies micro-services — app scaffolding, repo layer, middleware, and test utilities.
Documentation
use crate::context::RequestContext;
use crate::route::response::e500;
use crate::session::SessionHandler;
use actix_web::body::MessageBody;
use actix_web::dev::{ServiceRequest, ServiceResponse};
use actix_web::middleware::Next;
use actix_web::{FromRequest, HttpMessage, web};
use anyhow::anyhow;
use sqlx::PgPool;
use std::sync::Arc;

pub async fn get_context<T: 'static + Clone>(
    mut req: ServiceRequest,
    next: Next<impl MessageBody>
) -> Result<ServiceResponse<impl MessageBody>, actix_web::Error> {
    let session = {
        let (http_req, payload) = req.parts_mut();
        SessionHandler::from_request(http_req, payload).await
    }?;

    let session_data = session.get_session().map_err(e500)?;
    let db_pool = Arc::clone(
        &req.app_data::<web::Data<PgPool>>()
            .ok_or_else(|| anyhow!("Unable to access PgPool."))
            .map_err(e500)?
            .clone()
            .into_inner()
    );

    let custom = Arc::clone(
        &req.app_data::<web::Data<T>>()
            .ok_or_else(|| anyhow!("Unable to access Context."))
            .map_err(e500)?
            .clone()
            .into_inner()
    );
    let ctx = RequestContext::new(db_pool, Arc::new(session_data), custom).await.map_err(e500)?;
    req.extensions_mut().insert(ctx.clone());
    let resp = next.call(req).await?;

    if resp.status().is_success() {
        let mut guard = ctx.pg_context.tx.lock().await;
        if let Some(tx) = guard.take() {
            drop(guard);
            if let Err(e) = tx.commit().await {
                return Err(e500(e));
            }
        }
    };
    Ok(resp)
}