use actix_web::http::StatusCode; use actix_web::HttpResponse; use include_dir::Dir; use tera::Tera; fn tera_includedir_walk_folder_inner(collected: &mut Vec<(String, String)>, tera: &mut Tera, dir: &Dir) { for f in dir.files() { let halves: Vec<_> = f.path().file_name().unwrap().to_str().unwrap().split('.').collect(); if halves.last().unwrap() != &"tera" { debug!("Bad file: {:?}", f); continue; } let name = halves.first().unwrap(); let content = f.contents_utf8().unwrap(); let p = f.path().parent().unwrap().join(name); let template_path = p.to_str().unwrap(); debug!("Add template: {}", template_path); collected.push((template_path.to_string(), content.to_string())); } for subdir in dir.dirs() { tera_includedir_walk_folder_inner(collected, tera, subdir) } } pub(crate) trait TeraExt { fn add_include_dir_templates(&mut self, dir: &Dir) -> tera::Result<()>; fn build_response(&self, template: &str, context: &tera::Context) -> actix_web::Result { self.build_err_response(StatusCode::OK, template, context) } fn build_err_response(&self, code: StatusCode, template: &str, context: &tera::Context) -> actix_web::Result; } impl TeraExt for Tera { fn add_include_dir_templates(&mut self, dir: &Dir) -> tera::Result<()> { debug!("Walk dir: {:?}", dir.path()); let mut templates = vec![]; tera_includedir_walk_folder_inner(&mut templates, self, dir); self.add_raw_templates(templates) } fn build_err_response(&self, code: StatusCode, template: &str, context: &tera::Context) -> actix_web::Result { let html = self.render(template, context).map_err(|e| { actix_web::error::ErrorInternalServerError(e) })?; Ok(HttpResponse::build(code).body(html)) } }