From dc5b9d69e28c24fd5d6eb80a3a703dac5e40ef49 Mon Sep 17 00:00:00 2001 From: Tglman Date: Sat, 13 May 2023 13:59:53 +0100 Subject: [PATCH] feat: Allow multiple date formats in frontmatter --- crates/config/src/frontmatter.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/crates/config/src/frontmatter.rs b/crates/config/src/frontmatter.rs index 2ebd7a8f..6f510768 100644 --- a/crates/config/src/frontmatter.rs +++ b/crates/config/src/frontmatter.rs @@ -24,7 +24,10 @@ pub struct Frontmatter { pub tags: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub excerpt_separator: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde( + skip_serializing_if = "Option::is_none", + deserialize_with = "deserialize_date_time" + )] pub published_date: Option, #[serde(skip_serializing_if = "Option::is_none")] pub format: Option, @@ -46,6 +49,32 @@ pub struct Frontmatter { pub collection: Option, } +fn deserialize_date_time<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let s: std::borrow::Cow<'_, str> = serde::Deserialize::deserialize(deserializer)?; + if s == "now" || s == "today" { + // The date time parsing support now and today not needed in this context + Err(serde::de::Error::custom(format!( + "value '{}' not a valid date time format", + s + ))) + } else { + let parsed = DateTime::from_str(&s); + if parsed.is_some() { + Ok(parsed) + } else if !s.trim().is_empty() { + Err(serde::de::Error::custom(format!( + "value '{}' not a valid date time format", + s + ))) + } else { + Ok(None) + } + } +} + impl Frontmatter { pub fn empty() -> Self { Self::default()