From fbea42e5494c96174097bf3809a5b53d11d68a48 Mon Sep 17 00:00:00 2001 From: Vika Date: Tue, 8 Aug 2023 14:56:37 +0300 Subject: templates-neo: fix hacks around the `html` crate Finally I can properly add child elements without using the string hack. --- templates-neo/Cargo.toml | 2 +- templates-neo/src/mf2.rs | 95 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 9 deletions(-) (limited to 'templates-neo') diff --git a/templates-neo/Cargo.toml b/templates-neo/Cargo.toml index c0b426c..09abbfb 100644 --- a/templates-neo/Cargo.toml +++ b/templates-neo/Cargo.toml @@ -16,7 +16,7 @@ rand = "^0.8.5" [dependencies] ellipse = "^0.2.0" http = "^0.2.7" -html = "^0.5.2" +html = "^0.6.0" serde_json = "^1.0.64" include_dir = "^0.7.2" axum = "^0.6.18" diff --git a/templates-neo/src/mf2.rs b/templates-neo/src/mf2.rs index 706a301..c4d49a2 100644 --- a/templates-neo/src/mf2.rs +++ b/templates-neo/src/mf2.rs @@ -58,7 +58,76 @@ impl TryFrom for Card { }) } - todo!() + let mut props = card.properties.take(); + let uid = { + let uids = props.remove("uid").ok_or(Error::NoUid)?; + if let Some(PropertyValue::Url(uid)) = uids.into_iter().take(1).next() { + uid + } else { + return Err(Error::NoUid) + } + }; + + Ok(Self { + uid, + urls: props.remove("url").unwrap_or_default().into_iter() + .filter_map(|v| if let PropertyValue::Url(url) = v { + Some(url) + } else { + None + }).collect(), + name: props.remove("name") + .unwrap_or_default() + .into_iter() + .next() + .ok_or(Error::MissingProperty("name")) + .and_then(|v| match v { + PropertyValue::Plain(plain) => Ok(plain), + other => Err(Error::WrongValueType { + expected: "string", + got: other + }) + })?, + note: props.remove("note") + .unwrap_or_default() + .into_iter() + .next() + .and_then(|v| match v { + PropertyValue::Plain(plain) => Some(Ok(plain)), + other => Some(Err(Error::WrongValueType { + expected: "string", + got: other + })) + }) + .transpose()?, + photo: props.remove("photo") + .unwrap_or_default() + .into_iter() + .next() + .ok_or(Error::MissingProperty("photo")) + .and_then(|v| match v { + PropertyValue::Url(url) => Ok(Image::Plain(url)), + PropertyValue::Image(image) => Ok(Image::Accessible { + src: image.src, + alt: image.alt + }), + other => Err(Error::WrongValueType { + expected: "string", + got: other + }) + })?, + pronouns: props.remove("pronoun") + .unwrap_or_default() + .into_iter() + .map(|v| match v { + PropertyValue::Plain(plain) => Ok(plain), + other => Err(Error::WrongValueType { + expected: "string", + got: other + }) + }) + .collect::, _>>()? + }) } } @@ -110,8 +179,6 @@ impl Card { .href(url.clone()) .text(url) .build() - // XXX https://github.com/yoshuawuyts/html/issues/51 - .to_string() })); } @@ -274,7 +341,13 @@ impl TryFrom for Entry { .map(|v| -> Result, Error> { match v { PropertyValue::Temporal(Temporal::Timestamp(dt)) => { - todo!() + // This is incredibly sketchy. + let (date, time, offset) = (dt.date.clone().unwrap().data, dt.as_time().unwrap().data.clone(), dt.as_time().unwrap().offset.unwrap().data); + + date.and_time(time).and_local_timezone(offset).single().ok_or_else(|| Error::WrongValueType { + expected: "datetime with timezone", + got: PropertyValue::Temporal(Temporal::Timestamp(dt)) + }) }, other => Err(Error::WrongValueType { expected: "timestamp", @@ -313,13 +386,11 @@ impl Entry { .class("u-url u-uid") .href(String::from(self.uid)) .push(html::inline_text::Time::builder() - .text(self.published.to_string()) - .text(self.published.to_rfc3339_opts( + .text(self.published.format("%Y-%m-%d %a %H:%M:%S %z").to_string()) + .date_time(self.published.to_rfc3339_opts( chrono::SecondsFormat::Secs, false )) .build() - // XXX https://github.com/yoshuawuyts/html/issues/51 - .to_string() ))) .division(|div| div .text("Tagged") @@ -336,5 +407,13 @@ impl Entry { ) }) ) + .main(|main| { + if let Some(lang) = self.content.0.lang { + main.lang(lang); + } + + main.push(self.content.0.html) + }) + } } -- cgit 1.4.1