use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use crate::error::{Error, Result};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct Config {
pub template_paths: Vec<PathBuf>,
pub font_paths: Vec<PathBuf>,
pub use_system_fonts: bool,
}
impl Default for Config {
fn default() -> Self {
Self {
template_paths: vec![
PathBuf::from("./templates"),
PathBuf::from("./.typstgen/templates"),
],
font_paths: vec![],
use_system_fonts: true,
}
}
}
impl Config {
pub fn load(explicit_path: Option<&Path>) -> Result<Self> {
let candidate = match explicit_path {
Some(path) => Some(path.to_path_buf()),
None => {
let default_path = PathBuf::from("typstgen.toml");
default_path.exists().then_some(default_path)
}
};
let Some(path) = candidate else {
return Ok(Self::default());
};
let raw = std::fs::read_to_string(&path).map_err(|source| Error::Config {
path: path.clone(),
source,
})?;
Ok(toml::from_str(&raw)?)
}
pub fn template_roots(&self) -> Vec<PathBuf> {
let mut roots = Vec::new();
for path in &self.template_paths {
if let Ok(root) = path.canonicalize() {
if root.is_dir() && !roots.contains(&root) {
roots.push(root);
}
}
}
roots
}
}