62 lines
1.8 KiB
Rust
Raw Normal View History

use crate::generator::posts::parse::{parse_post, prepare_post, PostContent, PostMetadata};
use crate::generator::{content_path, HtmlContent, Post};
use compute_graph::rule::{Input, InputVisitable, Rule};
use std::fs;
use std::path::PathBuf;
pub fn list_post_files() -> anyhow::Result<Vec<PathBuf>> {
let posts_path = content_path("posts/");
let mut paths = vec![];
for ent in fs::read_dir(posts_path)? {
let Ok(ent) = ent else {
continue;
};
let Ok(ty) = ent.file_type() else {
continue;
};
if ty.is_dir() {
paths.push(find_index(ent.path()).expect("folder posts must have index file"));
} else {
paths.push(ent.path());
}
}
Ok(paths)
}
fn find_index(path: PathBuf) -> Option<PathBuf> {
let dir = fs::read_dir(path).ok()?;
dir.flatten()
.find(|e| e.path().file_stem().unwrap().eq_ignore_ascii_case("index"))
.map(|e| e.path())
}
#[derive(InputVisitable)]
pub struct ParsePost(pub PathBuf);
impl Rule for ParsePost {
type Output = Post<HtmlContent>;
fn evaluate(&mut self) -> Self::Output {
match parse_post(self.0.clone()) {
Ok(post) => prepare_post(post),
Err(e) => {
let path = self.0.to_string_lossy();
panic!("Failed to parse post {path}: {e}")
}
}
}
fn node_label(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0.file_stem().unwrap().to_string_lossy())
}
}
#[derive(InputVisitable)]
pub struct ExtractMetadata<C: PostContent>(pub Input<Post<C>>);
impl<C: PostContent + 'static> Rule for ExtractMetadata<C> {
type Output = PostMetadata;
fn evaluate(&mut self) -> Self::Output {
self.input_0().metadata.clone()
}
}