qrush 2.1.1

Lightweight Job Queue and Task Scheduler for Rust (Actix/Axum + Redis + Cron)
Documentation
use once_cell::sync::Lazy;
use std::sync::Arc;
use tera::{Context, Tera};
use crate::services::http_response::DashboardResponse;

// Centralized template list to keep code clean and DRY
const TEMPLATE_FILES: &[(&str, &str)] = &[
    ("layout.html.tera", include_str!("../templates/layout.html.tera")),
    ("dead_jobs.html.tera", include_str!("../templates/dead_jobs.html.tera")),
    ("metrics.html.tera", include_str!("../templates/metrics.html.tera")),
    ("queue_metrics.html.tera", include_str!("../templates/queue_metrics.html.tera")),
    ("delayed_jobs.html.tera", include_str!("../templates/delayed_jobs.html.tera")),
    ("summary.html.tera", include_str!("../templates/summary.html.tera")),
    ("cron_jobs.html.tera", include_str!("../templates/cron_jobs.html.tera")),
    ("failed_jobs.html.tera", include_str!("../templates/failed_jobs.html.tera")),
    ("retry_jobs.html.tera", include_str!("../templates/retry_jobs.html.tera")),
    ("errors/404.html.tera", include_str!("../templates/errors/404.html.tera")),
    ("errors/500.html.tera", include_str!("../templates/errors/500.html.tera")),
];

static TEMPLATES: Lazy<Arc<Tera>> = Lazy::new(|| {
    let mut tera = Tera::default();

    for (name, content) in TEMPLATE_FILES {
        tera.add_raw_template(name, content)
            .unwrap_or_else(|e| panic!("Failed to add {}: {}", name, e));
    }

    tera.autoescape_on(vec![]); // Disable autoescaping if rendering raw HTML
    Arc::new(tera)
});

pub async fn render_template(template_name: &str, ctx: Context) -> DashboardResponse {
    let tera = Arc::clone(&TEMPLATES);
    match tera.render(template_name, &ctx) {
        Ok(html) => DashboardResponse::html(html),
        Err(err) => {
            tracing::error!("Template render error: {:?}", err);
            let mut ctx = Context::new();
            ctx.insert("error", &err.to_string());
            let fallback_html = tera
                .render("errors/500.html.tera", &ctx)
                .unwrap_or_else(|_| "Internal Server Error".to_string());
            DashboardResponse::html_status(500, fallback_html)
        }
    }
}

// Optional helper for 404 rendering
pub async fn render_404() -> DashboardResponse {
    let tera = Arc::clone(&TEMPLATES);
    let ctx = Context::new();
    let html = tera
        .render("errors/404.html.tera", &ctx)
        .unwrap_or_else(|_| "Page Not Found".to_string());
    DashboardResponse::html_status(404, html)
}