1use std::path::{Path, PathBuf};
2
3use anyhow::Context;
4use mdbook::renderer::RenderContext;
5use serde::Deserialize;
6use toml::value::Table;
7
8use crate::Result;
9
10#[derive(Deserialize, PartialEq, Eq, Debug, Default, Clone, Copy)]
11#[serde(rename_all = "lowercase")]
12pub enum Builder {
13 #[default]
18 Foreground,
19 Experimental,
20 Background,
29 Slow,
33}
34
35#[derive(Deserialize)]
36#[serde(rename_all = "kebab-case", deny_unknown_fields)]
37struct DeConfig {
38 #[allow(unused)] command: Option<String>,
40
41 #[serde(default)]
42 builder: Builder,
43 collapsed: Option<bool>,
44 playgrounds: Option<bool>,
45 tsconfig: Option<PathBuf>,
46 inline_style_language: Option<String>,
47 optimize: Option<bool>,
48 polyfills: Option<Vec<String>>,
49 workdir: Option<String>,
50
51 html: Option<Table>,
52}
53
54pub struct Config {
56 pub builder: Builder,
60 pub collapsed: bool,
70 pub playgrounds: bool,
77 pub tsconfig: Option<PathBuf>,
79 pub inline_style_language: String,
83 pub optimize: bool,
89 pub polyfills: Vec<String>,
95
96 pub html: Option<Table>,
101
102 pub(crate) book_source_folder: PathBuf,
103 pub(crate) book_theme_folder: PathBuf,
104 pub(crate) angular_root_folder: PathBuf,
105 pub(crate) target_folder: PathBuf,
106}
107
108impl Config {
109 pub fn read<P: AsRef<Path>>(root: P) -> Result<Self> {
116 let root = root.as_ref();
117 let mut cfg =
118 mdbook::Config::from_disk(root.join("book.toml")).context("Error reading book.toml")?;
119 cfg.update_from_env();
120
121 Self::from_config(
122 &cfg,
123 root,
124 root.join(&cfg.build.build_dir),
126 )
127 }
128
129 pub fn new(ctx: &RenderContext) -> Result<Self> {
135 Self::from_config(&ctx.config, &ctx.root, ctx.destination.clone())
136 }
137
138 fn from_config(config: &mdbook::Config, root: &Path, destination: PathBuf) -> Result<Self> {
139 let angular_renderer_config = config
140 .get_renderer("angular")
141 .map_or_else(Default::default, ToOwned::to_owned);
142 let de_config: DeConfig = toml::Value::from(angular_renderer_config)
143 .try_into()
144 .context("Failed to parse mdbook-angular configuration")?;
145
146 let book_source_folder = root.join(&config.book.src);
147 let book_theme_folder = book_source_folder.join("../theme");
148
149 let angular_root_folder =
150 PathBuf::from(de_config.workdir.unwrap_or("mdbook_angular".to_owned()));
151 let angular_root_folder = if angular_root_folder.is_absolute() {
152 angular_root_folder
153 } else {
154 root.join(angular_root_folder)
155 };
156
157 let target_folder = destination;
158
159 Ok(Config {
160 builder: de_config.builder,
161 collapsed: de_config.collapsed.unwrap_or(false),
162 playgrounds: de_config.playgrounds.unwrap_or(true),
163 tsconfig: de_config.tsconfig.map(|tsconfig| root.join(tsconfig)),
164 inline_style_language: de_config.inline_style_language.unwrap_or("css".to_owned()),
165 optimize: de_config.optimize.unwrap_or(false),
166 polyfills: de_config.polyfills.unwrap_or_default(),
167
168 html: de_config.html,
169
170 book_source_folder,
171 book_theme_folder,
172 angular_root_folder,
173 target_folder,
174 })
175 }
176}