use std::collections::HashMap;
use std::fs::{self};
use std::path::Path;
use std::path::PathBuf;
use anyhow::Result;
use serde::Deserialize;
use toml::Value;
use tracing::debug;
#[derive(Deserialize, Debug)]
pub(crate) struct BookToml {
book: Option<Book>,
build: Option<Build>,
output: Option<Output>,
}
#[derive(Deserialize, Debug)]
pub(crate) struct Book {
src: Option<String>,
}
#[derive(Deserialize, Debug)]
pub(crate) struct Build {
#[serde(rename = "build-dir")]
build_dir: Option<String>,
}
#[derive(Deserialize, Debug)]
pub(crate) struct Output {
#[serde(flatten)]
extra: HashMap<String, Value>,
}
pub(crate) fn try_parse_book_toml<P: AsRef<Path>>(
book_root_dir_path: P,
) -> Result<(PathBuf, PathBuf, Option<PathBuf>)> {
let book_toml_path = book_root_dir_path.as_ref().join("book.toml");
debug!(
"try_parse_book_toml: book_toml_path: {}",
book_toml_path.display()
);
let book_toml: BookToml = toml::from_str(&fs::read_to_string(book_toml_path)?)?;
let markdown_dir_path = PathBuf::from(book_root_dir_path.as_ref())
.join(book_toml.book.and_then(|bk| bk.src).unwrap_or("src".into()));
let book_build_dir_path = PathBuf::from(book_root_dir_path.as_ref()).join(
book_toml
.build
.and_then(|bld| bld.build_dir)
.unwrap_or("book".into()),
);
let mut book_html_build_dir_path = book_build_dir_path.clone();
let mut book_markdown_build_dir_path = None;
debug!("{:?}", book_toml.output);
if let Some(output) = book_toml.output {
if output.extra.len() >= 2 {
book_html_build_dir_path = book_html_build_dir_path.join("html");
}
if output.extra.contains_key("markdown") {
book_markdown_build_dir_path = Some(book_build_dir_path.join("markdown"));
}
}
debug!(
"try_parse_book_toml: markdown_dir_path: {:?}; book_build_dir_path: {:?}; book_markdown_build_dir_path: {:?}",
markdown_dir_path, book_html_build_dir_path, book_markdown_build_dir_path,
);
Ok((
markdown_dir_path,
book_html_build_dir_path,
book_markdown_build_dir_path,
))
}
#[cfg(test)]
mod test {
}