rust_solid 0.1.0

Solid Support for Rust
Documentation
mod template_utils;

use actix_files::NamedFile;
use actix_web::{HttpRequest, HttpResponse};
use actix_web::http::StatusCode;
use serde_json::{Value};
use crate::template_utils::{ TEMPLATES, DEFAULT_TEMPLATE, to_template_name};
use tera::Context;


pub async fn render_views(req: HttpRequest, data: Value) -> HttpResponse {
    let path = req.path();
    let mut context = Context::new();
    for entries in data.as_object().into_iter() {
        for (key, value) in entries.into_iter() {
            context.insert(key, value);
        }
    }
    

    #[cfg(debug_assertions)]
    if path.eq("/__vite_ping") {
        println!("The vite dev server seems to be down...");
        return HttpResponse::NotFound().finish();
    }

    let template_path = to_template_name(req.path());
    let mut content_result = TEMPLATES.render(template_path, &context);

    println!("{:?}", content_result.as_ref().err());
    if content_result.is_err() {

        #[cfg(debug_assertions)] {
            // dev asset serving
            let asset_path = &format!("./resources{path}");
            if std::path::PathBuf::from(asset_path).is_file() {            
                return NamedFile::open(asset_path).unwrap().into_response(&req)
            }

            let public_path = &format!("./public{path}");
            if std::path::PathBuf::from(public_path).is_file() {
                return NamedFile::open(public_path).unwrap().into_response(&req)
            }
        }

        #[cfg(not(debug_assertions))] {
            // production asset serving
            let static_path = &format!("./public{path}");
            if std::path::PathBuf::from(static_path).is_file() {
                return NamedFile::open(static_path).unwrap().into_response(&req);
            }
        }
        content_result = TEMPLATES.render(DEFAULT_TEMPLATE, &context);
        if content_result.is_err() {
            // default template doesn't exist -- return 404 not found
            return HttpResponse::NotFound().finish()
        }
    }

    let content = content_result.unwrap();

    template_response(content)
}

fn template_response(content: String) -> HttpResponse {
    let mut content = content;
    #[cfg(debug_assertions)] {
        let inject: &str = r##"
        <!-- development mode -->
        <script type="module" src="http://localhost:3000/@vite/client"></script>
        "##;

        if content.contains("<body>") {
            content = content.replace("<body>", &format!("<body>{inject}"));
        } else {
            content = format!("{inject}{content}");
        }
    }

    HttpResponse::build(StatusCode::OK)
        .content_type("text/html")
        .body(content)
}