1use std::{collections::HashSet, env};
2
3use anyhow::Result;
4use cargo::{GlobalContext, core::Workspace, util::important_paths::find_root_manifest_for_wd};
5use mdbook_renderer::{RenderContext, Renderer, book::BookItem};
6
7use crate::{config::BuildConfig, parser::iframe::parse_iframes, trunk::build};
8
9pub struct TrunkRenderer;
10
11impl TrunkRenderer {
12 pub fn new() -> Self {
13 Self
14 }
15}
16
17impl Default for TrunkRenderer {
18 fn default() -> Self {
19 TrunkRenderer::new()
20 }
21}
22
23impl Renderer for TrunkRenderer {
24 fn name(&self) -> &str {
25 "trunk"
26 }
27
28 fn render(&self, ctx: &RenderContext) -> Result<()> {
29 let gctx = GlobalContext::default()?;
30 let workspace = Workspace::new(&find_root_manifest_for_wd(&env::current_dir()?)?, &gctx)?;
31
32 let builds = process_items(&ctx.book.items)?;
33
34 for build_config in builds {
36 let package_root = build_config.package_root(&workspace)?;
37 let dest_dir = ctx.destination.join(build_config.dest_name());
38
39 build(build_config, &package_root, &dest_dir)?;
44 }
45
46 Ok(())
51 }
52}
53
54fn process_items(items: &Vec<BookItem>) -> Result<HashSet<BuildConfig>> {
55 let mut builds = HashSet::new();
56
57 for section in items {
58 if let BookItem::Chapter(chapter) = section {
59 let blocks = parse_iframes(chapter)?;
60 for (_, config) in blocks {
61 builds.insert(config.build_config());
62 }
63
64 builds.extend(process_items(&chapter.sub_items)?);
65 }
66 }
67
68 Ok(builds)
69}