inertia-rust 2.4.6

A Rust server-adapter for building modern MVC web apps with Inertia.
Documentation
use std::collections::HashMap;

use crate::facade::InertiaFacade;
use crate::inertia::{InertiaHttpRequest, InertiaResponder, X_INERTIA, X_INERTIA_LOCATION};
use crate::{Component, Inertia, InertiaError, InertiaProps};
use actix_web::dev::ServiceResponse;
use actix_web::web::{Data, Redirect};
use actix_web::{HttpMessage, HttpRequest, HttpResponse};
use async_trait::async_trait;
use serde_json::{Map, Value};

use super::CustomViewData;

#[async_trait(?Send)]
impl InertiaFacade<HttpRequest, HttpResponse, Redirect> for Inertia {
    #[inline]
    async fn render(req: &HttpRequest, component: Component) -> Result<HttpResponse, InertiaError> {
        let inertia = extract_inertia(req);
        inertia.inner_render(req, component, None).await
    }

    #[inline]
    async fn render_with_props(
        req: &HttpRequest,
        component: Component,
        props: InertiaProps<'_>,
    ) -> Result<HttpResponse, InertiaError> {
        let inertia: &Inertia = extract_inertia(req);
        inertia.inner_render(req, component, Some(props)).await
    }

    #[inline]
    fn location(req: &HttpRequest, url: &str) -> HttpResponse {
        Inertia::inner_location(req, url)
    }

    #[inline]
    fn encrypt_history(req: &HttpRequest, encrypt: bool) {
        Inertia::inner_encrypt_history(req, encrypt);
    }

    #[inline]
    fn clear_history(req: &HttpRequest) {
        Inertia::inner_clear_history(req);
    }

    #[inline]
    fn back(req: &HttpRequest) -> Redirect {
        let inertia = extract_inertia(req);
        inertia.inner_back(req)
    }

    #[inline]
    fn back_with_errors<T: ToString>(req: &HttpRequest, errors: HashMap<T, Value>) -> Redirect {
        let inertia = extract_inertia(req);
        inertia.inner_back_with_errors(req, errors)
    }

    #[inline]
    fn view_data(req: &HttpRequest, data: HashMap<&str, Value>) {
        let custom_view_data = CustomViewData(Map::from_iter(
            data.into_iter().map(|(k, v)| (k.to_string(), v)),
        ));

        req.extensions_mut().insert(custom_view_data);
    }

    #[inline]
    fn check_is_inertia_request(req: &HttpRequest) -> bool {
        req.is_inertia_request()
    }
}

fn extract_inertia(req: &HttpRequest) -> &Inertia {
    match req.app_data::<Data<Inertia>>() {
        None => panic!("[Inertia Rust] There is no Inertia struct in AppData. Please, assure you have correctly configured Inertia."),
        Some(inertia) => inertia
    }
}

pub fn is_inertia_response<B: 'static>(res: &ServiceResponse<B>) -> bool {
    let headers = res.headers();

    headers.get(X_INERTIA).is_some()
        || headers.get("location").is_some()
        || headers.get(X_INERTIA_LOCATION).is_some()
}