org-static/src/config.rs

113 lines
2.9 KiB
Rust

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<Self> {
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<PathBuf> {
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();
}
}