use chrono::Utc;
use serde::Serialize;
#[derive(Debug, Serialize)]
struct Frontmatter {
title: String,
url: String,
date: String,
#[serde(skip_serializing_if = "Option::is_none")]
author: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
excerpt: Option<String>,
}
pub fn generate(
title: &str,
url: &str,
date: Option<&str>,
author: Option<&str>,
excerpt: Option<&str>,
) -> String {
let fm = Frontmatter {
title: title.to_string(),
url: url.to_string(),
date: date
.map(|s| s.to_string())
.unwrap_or_else(|| Utc::now().format("%Y-%m-%d").to_string()),
author: author.map(|s| s.to_string()),
excerpt: excerpt.map(|s| s.to_string()),
};
serde_yaml::to_string(&fm).unwrap_or_else(|_| String::new())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generate_with_all_fields() {
let fm = generate(
"Test Title",
"https://example.com",
Some("2024-01-15"),
Some("John Doe"),
Some("Test excerpt"),
);
assert!(fm.contains("title: Test Title"));
assert!(fm.contains("url: https://example.com"));
assert!(fm.contains("date:")); assert!(fm.contains("author: John Doe"));
assert!(fm.contains("excerpt: Test excerpt"));
}
#[test]
fn test_generate_with_auto_date() {
let fm = generate("Test", "https://example.com", None, None, None);
assert!(fm.contains("title: Test"));
assert!(fm.contains("url: https://example.com"));
assert!(fm.contains("date:"));
assert!(!fm.contains("author"));
assert!(!fm.contains("excerpt"));
}
#[test]
fn test_generate_minimal() {
let fm = generate("Minimal", "https://minimal.com", None, None, None);
assert!(fm.contains("title: Minimal"));
assert!(fm.contains("url: https://minimal.com"));
}
}