diff options
Diffstat (limited to 'templates-neo/src')
-rw-r--r-- | templates-neo/src/mf2.rs | 95 |
1 files changed, 87 insertions, 8 deletions
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<Item> 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::<Result<Vec<String>, _>>()? + }) } } @@ -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<Item> for Entry { .map(|v| -> Result<chrono::DateTime<chrono::FixedOffset>, 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) + }) + } } |