use anyhow::{Context, Result}; use askama::Template; use std::{fs, io, path::Path}; #[derive(Clone, Copy)] struct WebStates<'a> { auth: &'a str, error: &'a str, loading: &'a str, repo_selected: &'a str, repo_created: &'a str, button_on: &'a str, feature_on: &'a str, confirm_on: &'a str, } #[derive(Template)] #[template( ext = "html", path = "html/contentDefault.html", whitespace = "suppress" )] struct Default<'a> { config: crate::ServerConfig, features: Vec, content_text: String, state: WebStates<'a>, } #[derive(Template)] #[template(ext = "html", path = "html/base.html", whitespace = "suppress")] struct NotFound { config: crate::ServerConfig, content_text: String, } #[derive(Template)] #[template(path = "index.css", escape = "txt", whitespace = "suppress")] struct Css<'a> { state: WebStates<'a>, } pub fn make_templates(config: &crate::ServerConfig) -> Result<()> { let states = WebStates { auth: "auth", error: "error", loading: "loading", repo_selected: "repoSelected", repo_created: "repoCreated", button_on: "enabled", feature_on: "fEnabled", confirm_on: "enabled", }; let default = Default { config: config.clone(), features: crate::api::RepoFeature::iter() .map(|f| f.to_string()) .collect(), content_text: "awaiting authorization...".to_owned(), state: states, } .render() .context("Unable to process 'Default' template")?; fs::write("static/index.html", default).context("Could not write to static/index.html")?; let not_found = NotFound { config: config.clone(), content_text: "404: not found...".to_owned(), } .render() .context("Unable to process 'NotFound' template.")?; fs::write("static/404.html", not_found).context("Could not write to static/404.html")?; let css = Css { state: states } .render() .context("Unable to process 'CSS' template.")?; fs::write("static/index.css", css).context("Could not write to static/index.css")?; Ok(()) } fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { fs::create_dir_all(&dst)?; for entry in fs::read_dir(src)? { let entry = entry?; let ty = entry.file_type()?; if ty.is_dir() { copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?; } else { fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?; } } Ok(()) } pub fn copy_assets() -> Result<()> { fs::create_dir("static").context("Could not create directory 'static'.")?; copy_dir_all("assets", "static").context("Could not copy 'assets' into 'static'.")?; Ok(()) }