feat: add TOML site config for metadata

- Cargo.toml: Add toml and serde dependencies
- site.toml: New config with title, author, base_url
- src/config.rs: SiteConfig struct with load() function
- src/error.rs: Add Error::Config for parse errors
- src/main.rs: Load site.toml, thread config and page paths
  through generators
- src/templates.rs: Use config.title in nav/titles,
  config.author in footer, config.base_url for canonical URLs.

All three config fields verified in generated HTML output.
This commit is contained in:
Timothy DeHerrera
2026-01-24 21:47:47 -07:00
parent 71d5ac1e37
commit d166e86435
7 changed files with 215 additions and 30 deletions

51
src/config.rs Normal file
View File

@@ -0,0 +1,51 @@
//! Site configuration loading.
use crate::error::{Error, Result};
use serde::Deserialize;
use std::fs;
use std::path::Path;
/// Site-wide configuration loaded from site.toml.
#[derive(Debug, Deserialize)]
pub struct SiteConfig {
/// Site title (used in page titles and nav).
pub title: String,
/// Site author name.
pub author: String,
/// Base URL for the site (used for feeds, canonical links).
pub base_url: String,
}
impl SiteConfig {
/// Load configuration from a TOML file.
pub fn load(path: &Path) -> Result<Self> {
let content = fs::read_to_string(path).map_err(|e| Error::ReadFile {
path: path.to_path_buf(),
source: e,
})?;
toml::from_str(&content).map_err(|e| Error::Config {
path: path.to_path_buf(),
message: e.to_string(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_config() {
let toml = r#"
title = "Test Site"
author = "Test Author"
base_url = "https://example.com/"
"#;
let config: SiteConfig = toml::from_str(toml).unwrap();
assert_eq!(config.title, "Test Site");
assert_eq!(config.author, "Test Author");
assert_eq!(config.base_url, "https://example.com/");
}
}