use std::path::{Path, PathBuf};
use anyhow::{bail, Result};
use super::Format;
pub const DEFAULT_DIR: &str = "templates/wisp";
pub const TYPST_PARTIALS: &[(&str, &str)] = &[
("theme.typ", include_str!("assets/typst/theme.typ")),
("header.typ", include_str!("assets/typst/header.typ")),
("footer.typ", include_str!("assets/typst/footer.typ")),
("cover.typ", include_str!("assets/typst/cover.typ")),
("toc.typ", include_str!("assets/typst/toc.typ")),
];
pub const LOGO_SVG: &str = include_str!("assets/logo.svg");
pub fn bundled(format: Format) -> Result<&'static [(&'static str, &'static str)]> {
match format {
Format::Typst => Ok(TYPST_PARTIALS),
Format::Html => bail!(
"HTML partials are not available yet — the HTML render backends \
(WeasyPrint/Chromium) are opt-in and not wired. Use `--format typst`."
),
}
}
pub fn detect_format(dir: &Path) -> Option<Format> {
if dir.join("theme.typ").exists() {
Some(Format::Typst)
} else if dir.join("theme.css").exists() {
Some(Format::Html)
} else {
None
}
}
pub fn missing_partials(dir: &Path, format: Format) -> Vec<&'static str> {
format
.required_partials()
.iter()
.copied()
.filter(|name| !dir.join(name).exists())
.collect()
}
pub fn require_complete(dir: &Path, format: Format) -> Result<()> {
if !dir.exists() {
bail!(
"WISP template directory `{}` does not exist. Run `secunit wisp init` \
to scaffold the {} partials, review and commit them, then re-run export.",
dir.display(),
format
);
}
let missing = missing_partials(dir, format);
if !missing.is_empty() {
bail!(
"WISP template `{}` is missing required partial(s): {}. Run \
`secunit wisp init --force` to restore the defaults, or add them by hand.",
dir.display(),
missing.join(", ")
);
}
Ok(())
}
pub fn resolve_dir(root: &Path, override_dir: Option<&Path>) -> PathBuf {
match override_dir {
Some(d) if d.is_absolute() => d.to_path_buf(),
Some(d) => root.join(d),
None => root.join(DEFAULT_DIR),
}
}