genkit 0.3.1

A common generator kit for static site generator.
Documentation
use std::{
    fs,
    path::{Path, PathBuf},
};

use crate::{context::Context, data, jinja::init_environment, Entity, Generator};

use anyhow::Result;

#[derive(Debug)]
pub(crate) struct GenkitEngine<G> {
    source: PathBuf,
    dest: PathBuf,
    generator: G,
}

impl<G> GenkitEngine<G>
where
    G: Generator + Send,
{
    pub fn new(source: impl AsRef<Path>, dest: impl AsRef<Path>, generator: G) -> Result<Self> {
        let dest = dest.as_ref().to_path_buf();
        if !dest.exists() {
            fs::create_dir_all(&dest)?;
        }
        Ok(GenkitEngine {
            source: source.as_ref().to_path_buf(),
            dest,
            generator,
        })
    }

    pub fn build(&mut self, reload: bool) -> Result<()> {
        let instant = std::time::Instant::now();
        let source = self.source.as_ref();
        let dest = self.dest.as_ref();
        let mut entity = if reload {
            self.generator.on_reload(source)?
        } else {
            self.generator.on_load(source)?
        };

        entity.parse(source)?;

        let env = self
            .generator
            .on_extend_environment(source, init_environment(), &entity);

        if let Some(markdown_config) = self.generator.get_markdown_config(&entity) {
            let mut guard = data::write();
            guard.set_markdown_config(markdown_config);
        }

        let context = Context::new();
        entity
            .render(&env, context.clone(), dest)
            .expect("Render failed.");

        self.generator
            .on_render(&env, context, &entity, source, dest)?;
        println!("Build cost: {}ms", instant.elapsed().as_millis());
        Ok(())
    }
}