diff --git a/src/api.rs b/src/api.rs index 1663ef1..4e0545c 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::Deserialize; +use serde::{Deserialize, Deserializer, de::{self, Visitor}}; #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct UpResp { @@ -34,6 +34,8 @@ pub struct Meme { pub path: String, pub category: String, pub user: String, + #[serde(deserialize_with = "deserialize_timestamp")] + pub timestamp: i64, } impl Meme { @@ -62,3 +64,37 @@ impl User { .or(self.userdir.as_ref()) } } + +fn deserialize_timestamp<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + struct Vis; + + impl<'de> Visitor<'de> for Vis { + type Value = i64; + + fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + fmt.write_str( + "A timestamp in the form of a string or i64 (because tilera doesn't know integers \ + exist)", + ) + } + + fn visit_i64(self, v: i64) -> Result + where + E: de::Error, + { + Ok(v) + } + + fn visit_borrowed_str(self, v: &'de str) -> Result + where + E: de::Error, + { + v.parse().map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self)) + } + } + + deserializer.deserialize_any(Vis) +} diff --git a/src/util.rs b/src/util.rs index b3a653e..f3d61b1 100644 --- a/src/util.rs +++ b/src/util.rs @@ -152,6 +152,7 @@ pub enum MemeSorting { Link, Category, User, + Timestamp, } impl MemeSorting { @@ -171,6 +172,7 @@ impl MemeSorting { Self::Link => sort!(memes, link), Self::Category => sort!(memes, category), Self::User => sort!(memes, user), + Self::Timestamp => memes.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)), } } } @@ -184,6 +186,7 @@ impl FromStr for MemeSorting { "link" => Ok(Self::Link), "category" => Ok(Self::Category), "user" => Ok(Self::User), + "timestamp" => Ok(Self::Timestamp), _ => bail!("Invalid Meme sorting! options are id, link, category and user!"), } }