use std::path::PathBuf; use serde::{Deserialize, Serialize}; use crate::{error::Error, site::Site}; #[derive(Serialize, Deserialize, Debug)] #[serde(default)] pub struct Config { pub project_root: PathBuf, pub build_path: PathBuf, pub articles_path: PathBuf, pub theme_path: PathBuf, pub static_path: PathBuf, pub partials_path: PathBuf, pub site: Site, } impl Default for Config { fn default() -> Self { Config { site: Site::default(), project_root: ".".into(), build_path: "build".into(), articles_path: "articles".into(), theme_path: "theme".into(), static_path: "static".into(), partials_path: "partials".into(), } } } impl Config { pub fn find(path: PathBuf) -> crate::error::Result { if let Some(p) = find_config(path) { let content = std::fs::read_to_string(&p)?; let mut cfg: Config = toml::from_str(&content)?; cfg.project_root = p .canonicalize()? .parent() .ok_or_else(|| Error::new("Couldnt find project root"))? .to_path_buf(); Ok(cfg) } else { Err(Error::new("Config file not found")) } } pub fn get_build_path(&self) -> PathBuf { if self.build_path.is_relative() { PathBuf::from(&self.project_root).join(&self.build_path) } else { self.build_path.clone() } } pub fn get_articles_path(&self) -> PathBuf { if self.articles_path.is_relative() { PathBuf::from(&self.project_root).join(&self.articles_path) } else { self.articles_path.clone() } } pub fn get_theme_path(&self) -> PathBuf { if self.theme_path.is_relative() { PathBuf::from(&self.project_root).join(&self.theme_path) } else { self.theme_path.clone() } } pub fn get_static_path(&self) -> PathBuf { if self.static_path.is_relative() { PathBuf::from(&self.project_root).join(&self.static_path) } else { self.static_path.clone() } } pub fn get_partials_path(&self) -> PathBuf { if self.partials_path.is_relative() { PathBuf::from(&self.project_root).join(&self.partials_path) } else { self.partials_path.clone() } } } fn find_config(mut path: PathBuf) -> Option { let config_path = path.join("orgstatic.toml"); if config_path.is_file() { Some(config_path) } else if path.pop() { find_config(path) } else { None } } #[cfg(test)] mod tests { use super::*; #[test] fn test_find_config() { let path = PathBuf::from("examples/basic/articles/") .canonicalize() .unwrap(); Config::find(path).unwrap(); } }