natter/src/command/build/render.rs

72 lines
2.2 KiB
Rust
Raw Normal View History

use std::ffi::OsStr;
use std::path::PathBuf;
use include_dir::include_dir;
use include_dir::Dir;
use crate::blog_post::convert_blog_post_to_render_context;
use crate::blog_post::BlogPost;
use crate::error::CustomError;
use crate::render::DusterRenderer;
2023-10-22 16:40:58 -04:00
use crate::render::RendererIntegration;
static MAIN_TEMPLATES: Dir = include_dir!("$CARGO_MANIFEST_DIR/default_environment/templates/html");
pub(crate) struct SiteRenderer {
output_directory: PathBuf,
blog_posts: Vec<BlogPost>,
}
impl SiteRenderer {
pub(crate) fn new<P: Into<PathBuf>>(
output_directory: P,
blog_posts: Vec<BlogPost>,
) -> SiteRenderer {
SiteRenderer {
output_directory: output_directory.into(),
blog_posts,
}
}
pub(crate) async fn render_blog_posts(&self) -> Result<(), CustomError> {
let mut renderer_integration = DusterRenderer::new();
let (main_template, other_templates): (Vec<_>, Vec<_>) = MAIN_TEMPLATES
.files()
.filter(|f| f.path().extension() == Some(OsStr::new("dust")))
.partition(|f| f.path().file_stem() == Some(OsStr::new("main")));
if main_template.len() != 1 {
return Err("Expect exactly 1 main.dust template file.".into());
}
for entry in main_template {
load_template_from_include_dir(&mut renderer_integration, entry)?;
}
for entry in other_templates {
load_template_from_include_dir(&mut renderer_integration, entry)?;
}
for blog_post in &self.blog_posts {
let render_context = convert_blog_post_to_render_context(blog_post);
2023-10-22 16:40:58 -04:00
renderer_integration.render(render_context)?;
}
Ok(())
}
}
fn load_template_from_include_dir<RI: RendererIntegration>(
renderer_integration: &mut RI,
entry: &include_dir::File<'_>,
) -> Result<(), CustomError> {
let path = entry.path();
let name = path
.file_stem()
.ok_or("All templates should have a stem.")?
.to_str()
.ok_or("All template filenames should be valid utf-8.")?;
let contents = std::str::from_utf8(entry.contents())?;
renderer_integration.load_template(name, contents)?;
Ok(())
}