genkit/
engine.rs

1use std::{
2    fs,
3    path::{Path, PathBuf},
4};
5
6use crate::{context::Context, data, jinja::init_environment, Entity, Generator};
7
8use anyhow::Result;
9
10#[derive(Debug)]
11pub(crate) struct GenkitEngine<G> {
12    source: PathBuf,
13    dest: PathBuf,
14    generator: G,
15}
16
17impl<G> GenkitEngine<G>
18where
19    G: Generator + Send,
20{
21    pub fn new(source: impl AsRef<Path>, dest: impl AsRef<Path>, generator: G) -> Result<Self> {
22        let dest = dest.as_ref().to_path_buf();
23        if !dest.exists() {
24            fs::create_dir_all(&dest)?;
25        }
26        Ok(GenkitEngine {
27            source: source.as_ref().to_path_buf(),
28            dest,
29            generator,
30        })
31    }
32
33    pub fn build(&mut self, reload: bool) -> Result<()> {
34        let instant = std::time::Instant::now();
35        let source = self.source.as_ref();
36        let dest = self.dest.as_ref();
37        let mut entity = if reload {
38            self.generator.on_reload(source)?
39        } else {
40            self.generator.on_load(source)?
41        };
42
43        entity.parse(source)?;
44
45        let env = self
46            .generator
47            .on_extend_environment(source, init_environment(), &entity);
48
49        if let Some(markdown_config) = self.generator.get_markdown_config(&entity) {
50            let mut guard = data::write();
51            guard.set_markdown_config(markdown_config);
52        }
53
54        let context = Context::new();
55        entity
56            .render(&env, context.clone(), dest)
57            .expect("Render failed.");
58
59        self.generator
60            .on_render(&env, context, &entity, source, dest)?;
61        println!("Build cost: {}ms", instant.elapsed().as_millis());
62        Ok(())
63    }
64}