use anyhow::{anyhow, Result}; use serde::{ de::{self, Visitor}, Deserialize, Deserializer, }; #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct UpResp { pub files: Vec, } #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct CatsResp { pub categories: Vec, } #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct UsersResp { pub users: Vec, } #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct MemesResp { pub memes: Vec, } #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Category { pub id: String, pub name: String, } #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Meme { pub id: String, pub link: String, pub path: String, pub category: String, pub user: String, #[serde(deserialize_with = "deserialize_timestamp")] pub timestamp: i64, } impl Meme { pub fn file_name(&self) -> Result<&str> { self.path .split('/') .last() .ok_or_else(|| anyhow!("failed to get file name. server response invalid")) } } #[derive(Deserialize, Debug, PartialEq, Eq, Clone)] pub struct User { pub name: String, pub id: Option, pub tokenhash: Option, pub userdir: Option, pub dayuploads: String, } impl User { pub fn get_id(&self) -> Option<&String> { self.id .as_ref() .or_else(|| self.tokenhash.as_ref()) .or_else(|| 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) }