use std::sync::Arc; use axum::{Router, response::{Response, IntoResponse}, extract::Query, Extension, http::{HeaderName, HeaderValue}, routing::get}; use serde::Deserialize; use tera::{Context, Tera}; use tower_http::services::ServeDir; use crate::State; pub fn router() -> Router { Router::new() .fallback(not_found) .route("/", get(embed)) .nest_service("/static", ServeDir::new("public/static")) } #[derive(Deserialize, Debug)] struct Params { name: String, theme: Option } async fn not_found() -> Response { "do not the".into_response() } async fn embed(Extension(state): Extension>, Query(params): Query) -> Response { let Some(page) = state.pages.get(¶ms.name) else { return not_found().await }; let theme = match ¶ms.theme { Some(t) => t, None => "dark" }; let mut ctx = Context::default(); ctx.insert("prev", page.0.as_str()); ctx.insert("next", page.1.as_str()); ctx.insert("theme", theme); render(&state.templates, &ctx, "embed.html") } pub fn render(tera: &Tera, ctx: &Context, template: &str) -> Response { let rendered = match tera.render(template, ctx) { Ok(r) => r, Err(err) => { return format!("{err:?}").into_response() } }; let mut res = rendered.into_response(); res.headers_mut().insert( HeaderName::from_static("content-type"), HeaderValue::from_static("text/html") ); res }