natter/src/command/build/runner.rs
Tom Alexander e3b5f7f74f
Rename blog_post module to intermediate.
This module is mostly the intermediate representation of the AST, so the renaming is to make that more clear. The three forms are parsed => intermediate => render.

Parsed comes from Organic and is a direct translation of the org-mode text.

Intermediate converts the parsed data into owned values and does any calculations that are needed on the data (for example: assigning numbers to footnotes.)

Render takes intermediate and translates it into the format expected by the dust templates. The processing in this step should be minimal since all the logic should be in the intermediate step.
2023-10-27 13:10:21 -04:00

61 lines
2.2 KiB
Rust

use std::path::PathBuf;
use crate::cli::parameters::BuildArgs;
use crate::command::build::render::SiteRenderer;
use crate::config::Config;
use crate::error::CustomError;
use crate::intermediate::BlogPost;
pub(crate) async fn build_site(args: BuildArgs) -> Result<(), CustomError> {
let config = Config::load_from_file(args.config).await?;
let blog_posts = load_blog_posts(&config).await?;
let renderer = SiteRenderer::new(get_output_directory(&config).await?, blog_posts);
renderer.render_blog_posts(&config).await?;
Ok(())
}
/// Delete everything inside the output directory and return the path to that directory.
async fn get_output_directory(config: &Config) -> Result<PathBuf, CustomError> {
let output_directory = config.get_output_directory();
if !output_directory.exists() {
tokio::fs::create_dir(&output_directory).await?;
} else {
let mut existing_entries = tokio::fs::read_dir(&output_directory).await?;
while let Some(entry) = existing_entries.next_entry().await? {
let file_type = entry.file_type().await?;
if file_type.is_dir() {
tokio::fs::remove_dir_all(entry.path()).await?;
} else {
tokio::fs::remove_file(entry.path()).await?;
}
}
}
Ok(output_directory)
}
async fn get_post_directories(config: &Config) -> Result<Vec<PathBuf>, CustomError> {
let mut ret = Vec::new();
let mut entries = tokio::fs::read_dir(config.get_posts_directory()).await?;
while let Some(entry) = entries.next_entry().await? {
let file_type = entry.file_type().await?;
if file_type.is_dir() {
ret.push(entry.path());
}
}
Ok(ret)
}
async fn load_blog_posts(config: &Config) -> Result<Vec<BlogPost>, CustomError> {
let root_directory = config.get_root_directory().to_owned();
let post_directories = get_post_directories(&config).await?;
let load_jobs = post_directories
.into_iter()
.map(|path| tokio::spawn(BlogPost::load_blog_post(root_directory.clone(), path)));
let mut blog_posts = Vec::new();
for job in load_jobs {
blog_posts.push(job.await??);
}
Ok(blog_posts)
}