use std::path::Path;
use yog_formats::book::page_type::{PageType, compile, is_book_page};
use crate::diagnostics::Diagnostic;
use crate::ui::yui::{self, Element};
pub(crate) fn is_book_ui(root: &Element) -> bool {
is_book_page(root) || yog_formats::book::layout::is_recipe_layout(root)
}
pub(crate) fn find(root: &Path, ns: &str, errors: &mut Vec<Diagnostic>) -> Vec<PageType> {
components(root, errors, is_book_page, |el, _| compile(el, ns))
}
pub(crate) fn find_layouts(
root: &Path,
ns: &str,
errors: &mut Vec<Diagnostic>,
) -> Vec<(String, yog_formats::book::layout::RecipeLayout)> {
components(
root,
errors,
yog_formats::book::layout::is_recipe_layout,
|el, shown| yog_formats::book::layout::compile(el, ns).map(|l| (shown.to_owned(), l)),
)
}
fn components<T>(
root: &Path,
errors: &mut Vec<Diagnostic>,
is: impl Fn(&yui::Element) -> bool,
compile: impl Fn(&yui::Element, &str) -> Result<T, Diagnostic>,
) -> Vec<T> {
let mut out = Vec::new();
for file in yui::find_yui_files(&root.join(yog_ids::project::SRC)) {
let Ok(text) = std::fs::read_to_string(&file) else {
continue;
};
let Ok(el) = yui::parse_xml(&text) else {
continue;
};
if !is(&el) {
continue;
}
let shown = file
.strip_prefix(root)
.unwrap_or(&file)
.display()
.to_string();
match compile(&el, &shown) {
Ok(t) => out.push(t),
Err(e) => errors.push(screen_problem(e).in_file(&shown)),
}
}
out
}
fn screen_problem(found: Diagnostic) -> Diagnostic {
found.or_code(yog_ids::build_problem::SCREEN)
}