69 lines
1.8 KiB
Rust
69 lines
1.8 KiB
Rust
|
use std::sync::Arc;
|
||
|
|
||
|
use minijinja::Environment;
|
||
|
use pathdiff::diff_paths;
|
||
|
use tokio::sync::Mutex;
|
||
|
use tracing::info;
|
||
|
|
||
|
#[derive(Clone)]
|
||
|
pub struct Templates {
|
||
|
env: Arc<Mutex<Environment<'static>>>,
|
||
|
}
|
||
|
|
||
|
pub type Error = Box<dyn std::error::Error>;
|
||
|
|
||
|
impl Templates {
|
||
|
pub fn empty() -> Self {
|
||
|
let env = Arc::new(Mutex::new(Environment::new()));
|
||
|
Self { env }
|
||
|
}
|
||
|
|
||
|
pub async fn try_load() -> Result<Self, Error> {
|
||
|
let mut result = Self::empty();
|
||
|
result.load_env().await?;
|
||
|
Ok(result)
|
||
|
}
|
||
|
|
||
|
pub async fn start_watcher(&mut self) {
|
||
|
info!("TODO: Implement template watcher");
|
||
|
}
|
||
|
|
||
|
pub async fn load_env(&mut self) -> Result<(), Error> {
|
||
|
info!("Loading templates...");
|
||
|
for d in walkdir::WalkDir::new("src/templates") {
|
||
|
match d {
|
||
|
Ok(d) => {
|
||
|
if d.file_type().is_dir() {
|
||
|
continue;
|
||
|
}
|
||
|
let filename: String = diff_paths(d.path(), "src/templates")
|
||
|
.unwrap()
|
||
|
.to_string_lossy()
|
||
|
.into_owned();
|
||
|
info!("Loading template {filename:#?} ({d:#?})");
|
||
|
self.env
|
||
|
.clone()
|
||
|
.lock()
|
||
|
.await
|
||
|
.add_template_owned(filename, std::fs::read_to_string(d.path())?)?;
|
||
|
}
|
||
|
Err(_) => todo!(),
|
||
|
}
|
||
|
}
|
||
|
info!("Done loading templates!");
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub async fn render<S: serde::ser::Serialize>(
|
||
|
&self,
|
||
|
template_name: &str,
|
||
|
context: S,
|
||
|
) -> Result<String, minijinja::Error> {
|
||
|
self.env
|
||
|
.lock()
|
||
|
.await
|
||
|
.get_template(template_name)?
|
||
|
.render(context)
|
||
|
}
|
||
|
}
|